C++:结构数组赋值中 const char* 的意外结果
我的代码:
#include <pthread.h>
#include <iostream>
#include <vector>
using namespace std;
typedef struct {
int id;
const char* name;
const char* out;
} thread_info;
int main(int argc, char const *argv[])
{
int err = 0;
std::vector<thread_info> info_vec;
info_vec.resize(10);
for(int i = 0; i < 10; i++) {
//info_vec[i].id = i;
info_vec[i].name = to_string(i).c_str();
}
int count = 10;
for (size_t i = 0; i < count; i++)
{
/* code */
//cout << info_vec[i].id << endl;
cout << info_vec[i].name << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
结果是:
9
9
9
9
9
9
9
9
9
9
Run Code Online (Sandbox Code Playgroud)
要求解释为什么结果不是“1 2 3 4 5 6 7 8 9”我的代码有什么问题?
要求解释为什么结果不是“1 2 3 4 5 6 7 8 9”我的代码有什么问题?
ps:如果我使用 id 而不是 name,它可以打印“1 2 3 4 5 6 7 8 9”
to_string(i)是临时的,因此内容在 后被释放(或其生命周期已结束)info_vec[i].name = to_string(i).c_str();,即指针悬空。
理论上,解引用释放的指针是UB,即任何事情都可能发生。实际上,正如您的编译器选择执行的操作(这不是可移植的[^1]),它们都是9因为它们都指向同一个地方;这是因为每个字符串都被分配,然后释放,下一个字符串在同一位置分配,依此类推。最终的字符串是9,因此你到达9这里。然而,由于最终的字符串也被释放,如果其他内容占用了这块内存,9也会被覆盖。
您需要做的是制作 egname std::string而不是const char*,它将保存内容,因为您将其复制到另一个地方。
[^1]:正如@Chris所说,由于它是UB,看起来指向同一位置的悬空指针可能会得到不同的内容。