std::string.assign() the right way

string s;
char str[] = ""; //this is usually not empty, but if i receive a empty message I need to know that I won't come across any surprises / undefined behavior if I do one of the examples below.



Ex.1:
s.assign(str,str + 2); // this adds strange characters to the std::string but it's not a problem for me if this happen sometime.


Ex.2:
s.assign(str, str); // Here I'm worried about that the first & last are the same.
Last edited on
This:
 
char str[] = "";
is equivalent to this:
 
char str[1] = {0};
so all you can with str and s is either
 
s.assign(str, str); // equivalent to s.clear(); 
or
 
s.assign(str, str + 1);


this is usually not empty, but if i receive a empty message
What exactly do you mean? str has constant length.

this adds strange characters to the std::string but it's not a problem for me if this happen sometime.
Any time you end up with garbage it's a sure sign that you have undefined behavior in the program and you should address it immediately.
this adds strange characters to the std::string

You are assigning characters from outside your C string's boundaries in the first example.

Yes, the C string is at the same time empty of any useful content, yet it has the NULL character as the first and only character in the string. So C string library functions will report be able to calculate the C string's size.

If you are wanting to assign the entire contents of your C string to your std::string then use operator=. std::string::assign is a rather brutal and potentially dangerous way to do it as your two examples show.


Any time you end up with garbage it's a sure sign that you have undefined behavior in the program and you should address it immediately.

When we have the string, we check that it's equal to what we expect. If it's not, we won't continue doing stuff with that value. So if it is garbage of type string, then there is no real danger, is there?


If you are wanting to assign the entire contents of your C string to your std::string then use operator=. std::string::assign is a rather brutal and potentially dangerous way to do it as your two examples show.


I don't need the whole thing, only part of it. Thats why
It seems that the only real danger is if we pass in a (first) that is greater than (last) ? (comparing positions)
When we have the string, we check that it's equal to what we expect. If it's not, we won't continue doing stuff with that value. So if it is garbage of type string, then there is no real danger, is there?
You can't reason about undefined behavior. Period.
It's your prerogative to be sloppy, but I assure you it will come back to bite you in the ass.
char str[] = ""; //this is usually not empty, but ...

Your entire premise is wrong.

Trying to fix this wrong idea by using std::string is just a waste of time.

From your series of posts, it seems you're trying to write network server code without understanding any of the fundamentals.

You need to understand the idea of network layers. There are two popular models, the more practical one from the IETF: https://en.wikipedia.org/wiki/Internet_protocol_suite and some knowledge of the more abstract one, the OSI model: https://en.wikipedia.org/wiki/OSI_model

Understanding network coding won't hurt either.

You cannot instruct a computer to do something without understanding it yourself. I suggest you understand the ideas before writing code; play with code, yes, but don't try to build your app.
Last edited on

char str[] = ""; //this is usually not empty, but ...


You all seem to panic over this. Used this to demonstrate an empty string. In the program it is "non const char array" which can have varying data.

Mybad, I'll try to be clearer in the future;)
1
2
3
4
void foo(char *str){
    assert(*str == 0);
    s.assign(str, str + /*???*/);
}
Communicating ideas effectively is an important skill for a programmer.
volang wrote:
So if it is garbage of type string, then there is no real danger, is there?
helios wrote:
You can't reason about undefined behavior. Period.

Here's a "for instance." If str is a local variable then it's stored on the stack. If your program hits just the right call stack, then str might end up at the boundary of a page in memory. When you access the byte beyond str, BOOM! You've accessed an invalid memory address and your program crashes. Naturally this happens one time in a million runs and becomes nearly impossible to debug.

Don't. Just don't. Don't knowingly write invalid code, especially out of laziness. It will come back to bite you. Code needs to work.
That's not even the worst of it. An immediate crash is easy to find and fix, but a memory corruption bug can manifest arbitrarily far from the code that causes it. So you're doing something perfectly correct and your program crashes because you performed an invalid read thirty minutes ago in an entirely different source file.
Or maybe the program doesn't even crash, it just subtly and silently corrupts your data.
Last edited on

char str[] = ""; //this is usually not empty, but ...

You all seem to panic over this. Used this to demonstrate an empty string. In the program it is "non const char array" which can have varying data.


This is not the line that panics us. This line is is a perfectly valid line of code. It defines an array with a length of 1 that contains the null character. That's it.

As far as "varying data", it can only have 256 legal configurations. The array will always be exactly 1 character long, and can only contain values ranging from -128 to +127.

I'm not sure what you mean by "demonstrate an empty string". If you mean you are using it to compare to std::strings, you can just use the std::string.empty() to determine that.

What panics us is line:
s.assign(str,str + 2); // this adds strange characters to the std::string but it's not a problem for me if this happen sometime.

You cannot safely reference the 3rd character in a 1-character array. You just can't.

You appear to be trying to write code for a fairly complex application without having a firm understanding of the fundamentals. If you insist on writing code using char[] and such, start with some toy programs first. Understand why you get funny characters and such, and eliminate this behavior. When you have rock-solid code to work from, then start hacking your network communication.
helios wrote:
a memory corruption bug can manifest arbitrarily far from the code that causes it
True, but the code shown doesn't corrupt memory. It's reading from from out of bounds, but if the read succeeds, the write should work fine. One can definitely argue that undefined behavior is undefined behavior and I agree with that, but in this case I think the practical problem is reading out of bounds, not appending garbage to a string.
For example, you might read an undefined value into the string and later make a decision on the garbage value, causing a jump to nowhere.
Topic archived. No new replies allowed.