好的,所以基本上我有一个类似的结构
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
。