存储const char*会给我随机字符

Storing const char* gives me random characters

本文关键字:随机 字符 const char 存储      更新时间:2023-10-16

好的,所以基本上我有一个类似的结构

struct person{
   const char* name;
   const char* about_me;
   const char* mom_name;
   const char* age;
};

然后为了使我的代码通用,我有

struct Person PersonAsArray[MAX_ARRAY - 1];

然后我有一个文件,它读取了很多东西,最终我解析了它。但当我解析它时,我得到了一个std::string,所以我必须将它转换为const char*,所以下面是我的更多代码:

getline(file, line);
//break the line up into 2 parts (because in the file its "name=John")
//these two parts are called id and value
if(id == "name"){
    const char* CCvalue = value.c_str();
    cout << CCvalue << endl; // its fine here
    PersonAsArray[i].name = CCvalue; //i is incremented each time i need a new struct
}
if(id == "age"){
    PersonAsArray[i].age = atoi(value.c_str());
}
//and some more of this stuff... eventually i have
cout << PersonAsArray[0].name << endl;
cout << PersonAsArray[0].about_me << endl;
cout << PersonAsArray[0].mom_name << endl;
cout << PersonAsArray[0].age << endl;

但当我最终完成所有的事情时,我最终会得到这样的东西。我只是有点好奇发生了什么,为什么它会给我符号?并且它并不总是相同的符号。有时我得到了笑脸,有时我甚至没有得到整排的矩形。我不知道我在做什么,这可能是我编码中的一些主要缺陷。但当我做类似的事情时也会发生这种情况

string hi = "hello"
for(i = 0; hi[i] != ''; i++){
    char x = hi[i];
    string done = "";
    if(x == 'h') done += "abc";
    if(x == 'e') done += "zxc";
    if(x == 'l') done += "aer";
    if(x == 'o') done += "hjg";
    cout << done;
}

我想我记得我得到了这些花状的形状,我想我甚至看到了汉字,但它们再次不一致,即使我在程序中没有改变任何东西,如果我运行几次,我会看到几个不同的符号组合,有时不会出现任何符号。

您没有阅读文档!

std::string::c_str()返回的值不会永远存在。

c_str()获得的指针可以通过以下方式无效:

  • 将对字符串的非常数引用传递给任何标准库函数,或者
  • 调用字符串上的非常数成员函数,不包括operator[]at()front()back()begin()rbegin()end()rend()

析构函数就是这样一个"非常数成员函数"。

一旦指针无效,就不能使用它。当你尝试时,你要么将数据存储在内存中的某个任意位置(你的计算机徒劳地试图理解这些数据,就好像它是文本一样,导致了你描述的花朵和汉字),要么出现了其他不可预测的奇怪症状。

不幸的是,您没有提供一个完整的、最小的测试用例,所以我们不知道value是如何真正融入您的代码的,但很明显,在您的"这里很好"和有问题的代码之间,它并不能完好无损地存在。

不要将std::string::c_str()的结果长期保存。没有必要,也很少有用。

tl;dr使person存储std::string s,而不是悬挂指针

问题是您有类似的东西

{
  std::string value;
  // fill value
  PersonsAsArray[i].name = value.c_str();
}

现在,value是一个局部变量,它在退出声明它的作用域时被销毁。您将指向其内部数据的指针存储到.name中,但不复制它,因此销毁后它指向垃圾。

您应该有一个std::string name字段,而不是const char*,它将自己及其复制分配运算符处理内容的复制和保留,或者手动为const char*分配内存,例如通过strdup