Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Interfacing with C library, why does this not work (strcpy, std::string, char *)?

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading