C++结构体数组中const char*赋值异常的原因及代码问题排查
问题原因拆解
- 核心问题出在临时字符串的生命周期:
to_string(i)会生成一个临时的std::string对象,这个对象只在当前行语句执行时存在,语句执行完就会被销毁回收内存。 c_str()返回的是这个临时string内部字符数组的指针,一旦临时对象消失,这个指针就变成了悬空指针——指向已经被释放的内存区域。- 巧合的是,循环里每次创建的临时string大概率会被分配到同一块内存地址,最后一次循环i=9时,临时string存的是"9",虽然对象销毁了,但这块内存的内容暂时没被覆盖,所以所有结构体里的name指针都指向这块内存,最终输出全是"9"。
而id是int类型,赋值时是直接拷贝数值,不存在指针指向失效的问题,所以能正常输出0到9。
修复方案
推荐优先用第一种,更符合C++的内存管理习惯:
- 把结构体的name改成std::string类型
直接存储字符串对象,不用手动管指针和内存,C++会自动处理生命周期:
#include <vector> #include <string> #include <iostream> struct thread_info { int id; std::string name; // 替换const char*为std::string }; int main() { std::vector<thread_info> threads(10); for (int i = 0; i < 10; ++i) { threads[i].id = i; threads[i].name = std::to_string(i); // 直接赋值即可 } for (const auto& info : threads) { std::cout << "id: " << info.id << ", name: " << info.name << '\n'; } return 0; }
- 手动分配内存拷贝字符串(不推荐,容易漏释放)
如果必须用const char*,得为每个name单独分配内存,把字符串内容拷贝进去:
#include <vector> #include <string> #include <iostream> #include <cstring> struct thread_info { int id; const char* name; }; int main() { std::vector<thread_info> threads(10); for (int i = 0; i < 10; ++i) { threads[i].id = i; std::string temp_str = std::to_string(i); // 分配足够存字符串+终止符的内存 char* buf = new char[temp_str.size() + 1]; strcpy(buf, temp_str.c_str()); threads[i].name = buf; } // 输出测试 for (const auto& info : threads) { std::cout << "id: " << info.id << ", name: " << info.name << '\n'; } // 必须手动释放内存,否则会泄漏 for (auto& info : threads) { delete[] info.name; } return 0; }
内容的提问来源于stack exchange,提问作者qings Azure
相关产品推荐
相关产品推荐

