C++使用c_str()给结构体赋值时字符串意外关联同一变量问题
问题原因拆解
核心原因是你的结构体存储的是指向std::string内部缓冲区的裸指针,而非独立的字符串副本,指针指向的内容完全和tmp变量绑定。
具体执行逻辑
std::string::c_str()返回的是当前std::string对象内部存储C风格字符串的内存地址,这个地址的有效性、指向的内容完全随原std::string对象变化:原对象内容修改、销毁都会导致指针失效或内容变更。- 第一次执行
tmp = "foo"时,tmp内部缓冲区存储了foo\0,你把这个缓冲区的地址赋值给test.server,此时输出test.server得到foo符合预期。 - 第二次执行
tmp = "bar"时,由于foo和bar长度相同,std::string直接覆写了原有内部缓冲区的内容,地址没有变化,只是内容变成了bar\0。你把同一个地址又赋值给test.user,此时输出test.user得到bar也符合预期。 - 最后输出
test.server和test.user时,两个指针指向的是同一个tmp的内部缓冲区,此时缓冲区内容已经是bar,所以两个输出都是bar。
修复方案
- 方案1:结构体成员直接使用
std::string类型,赋值时会自动做内容拷贝,完全和原临时变量独立:
struct test_struct{ std::string server, user; }; // 后续直接赋值即可:test.server = tmp;
- 方案2:如果必须存储
const char*,需要手动申请内存拷贝字符串内容,不要直接保存c_str()的返回值:
test.server = strdup(tmp.c_str()); // 程序退出前记得手动free释放内存,避免泄漏
内容的提问来源于stack exchange,提问作者Alexander Minor
相关产品推荐
相关产品推荐

