Reputation: 3617
I have a struct that needs to store const char * for later. The string gets destroyed by then. The code that i have till now for the same is
HttpRequest* send(string reply)
{
int len = strlen(reply.c_str());
char *buffer = new char[len+1];
strncpy(buffer, reply.c_str(), len);
cout << "LEN:"<<reply.length()<<endl;
cout << "OG:"<<reply<<endl<<"TC:"<<buffer<<endl<<"CS"<<reply.c_str()<<endl;
this->res.response = "test";
return this;
};
res.response
is the char * that i want to store the value in. The output from cout that i am getting is
LEN:5
OG:hello
TC:hello�������������������q{
CShello
This behavior is pretty strange to me. Can someone please explain what i am doing wrong. Also the above code shows me using strlen
but i am getting the same result using length()
in c++ also.
Also it is worth mentioning that this happens only the first time that i invoke this, after that it goes fine.
Upvotes: 0
Views: 1591
Reputation: 310950
The problem is that this statement
strncpy(buffer, reply.c_str(), len);
does not copy the terminating zero ( '\0' ) of the original string to buffer
.
You should use the standard C function strlen
with objects of type std::string
only in case when the objects contain embedded zeroes. Otherwise use member functions of the class std::string
size
or length
.
Instead of the standard C function strncpy
you could use standard C function strcpy
to copy the zero-terminated string in the buffer.
For example
char *buffer = new char[len+1];
strcpy( buffer, reply.c_str() );
Upvotes: 1
Reputation: 75062
Your arguments to strncpy()
make the function misunderstand that there is no space for terminating null-character, so it isn't written. Correct the argument like
strncpy(buffer, reply.c_str(), len+1);
In this code, it is guaranteed that the length of buffer is sufficient to store the string, so you can simply use strcpy()
instead of the strncpy()
like this:
strcpy(buffer, reply.c_str());
You can use strdup()
function if your system supports it. Using it, the lines
int len = strlen(reply.c_str());
char *buffer = new char[len+1];
strncpy(buffer, reply.c_str(), len);
can be replaced with
char *buffer = strdup(reply.c_str());
Note that strdup()
is a function from C and it uses malloc()
internally, so you must use free()
, not delete[]
, to free the memory allocated via strdup()
.
Upvotes: 3
Reputation: 76245
Don't use strncpy
until you've read and understood its documentation. And then don't use it. It's a very specialized function, and there's no need to deal with its quirks here. The code in the question allocates enough space for the result, so just use strcpy
.
Upvotes: 1
Reputation: 10727
You never put the null terminator:
char *buffer = new char[len+1];
strncpy(buffer, reply.c_str(), len);
buffer[len] = 0; // <-- HERE
strncpy
doesn't add it.
Upvotes: 10