I am writing a program that needs to interface with an external C library. I have to pass
a char* parameter to a function, to get a name of a data set. Essentially the situation look
like below
#include <string>
#include <iostream>
#include <string.h>
void give_name(char* name) {
const char* name_test = "test";
strcpy(name, name_test);
}
int main() {
std::string a;
a.reserve(10);
char b[10];
give_name(&a[0]);
give_name(b);
std::cout << a << std::endl;
std::cout << b << std::endl;
}
Now, I am stumped, why a does not contain "test" in my example and instead is empty:
ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 0
test
The above was compiled with gcc12.2 with -std=c++11.
I even looked in the inside of the "give_name" function with gdb (in the real library
and not a simple example above), and there the variable corresponding to name contains proper text.
I feel like I am missing something important, any help? Even funnier that this works in different place of the code? Is this the mythical undefined behaviour?
>Solution :
While you reserved storage in a to give it a capacity of 10, its size is still zero. You are not supposed to modify the string buffer like this.
The stream output for std::string will write the characters up to its known end of string, not the NUL-terminator if you happened to break the rules. So you might see your "expected" result if you do:
std::cout << a.data() << std::endl;
But that is a super bad idea. You have already broken the string, and it cannot fulfill its behavioral guarantees as per the standard.
In general it’s not recommended to write NUL-terminated strings directly into a std::string buffer. But if you do, you should calculate the new length and resize the string accordingly.