const char * c++ std::map 中的重复数据
const char * duplicate data inside of std::map in c++
我有一个罕见的问题。
我已经将结构存储到 std::map,
插入第一个数据并正常运行,但是当我尝试存储多个结构数据时,结构内所有 "seconds" 值的所有 const char*
都丢失了,并被新数据替换。
我恢复代码:
struct Emitter{
.
.
const char * name;
const char * file;
}
Emitter metadata;
在我插入结构之前,我用这段代码填充 const char * 变量(我从 XML 获得信息)
std::string name_tmp= atts.getString("name", "ed");
char tmp[50];
strcpy(tmp, name_tmp.c_str());
metadata.name= tmp;
std::string file_tmp= atts.getString("file", "ed");
char tmp2[50];
strcpy(tmp2, file_tmp.c_str());
metadata.file= tmp2;
地图的key,是Emitter结构体里面的名字;
typedef std::map<std::string, Emitter> Dictionary;
typedef std::pair<std::string, Emitter> Defination;
Dictionary::iterator it = map.find(name);
if (it != map.end())
map[metadata.name] = data;
else{
if (map.size() == 0)
map.insert(Defination(metadata.name, metadata));
else{
ParticlesDictionary::iterator i = map.begin();
map.insert(i, Defination(metadata.name, metadata));
}
}
当我打印插入堆栈输出的过程时,我得到这个:
// key ---> struct value (name) ---> struct value (file)
//first time
key1 --> eddy --> fileName1
//second time
key1 --> eddy1-->fileName2
key2 --> eddy1-->fileName2
//third time
key1 --> eddy2-->fileName3
key2 --> eddy2-->fileName3
key3 --> eddy2-->fileName3
为什么会这样?
请帮忙
您的 const char*
字段指向不属于 struct
的缓冲区。这意味着当数组 tmp
和 tmp2
超出范围时,它们使用的 space 可用于其他数据。
在您的情况下,它会在下一个 struct
中重复使用。要解决此问题,您应该分配 struct
拥有的内存:通过将 const char*
字段替换为 std::string
字段,或使用 new
和 delete
.
无论您是在 SO 上提出问题还是尝试自己解决此类问题,第一步都是构建 MVCE 或 SSCE - 问题的小型离散再现。
使用您的代码,我们将专注于以下方面:
#include <iostream>
struct A {
const char* text;
};
void f(A& a, const char* text) {
char localTxt[50];
strcpy(lt, text);
a.text = localTxt;
}
int main() {
A a, b;
f(a, "hello");
f(b, "world");
std::cout << "But afterwards:" << std::endl;
std::cout << "a = " << a.text << ", b = " << b.text << "\n";
}
我们已经放弃了你在这里所做的大部分工作,并在 "what happens when I put this value into a structure" 上进行了磨练。
而这里的问题是 localText
存在于堆栈中,我们获取了它的地址并将 that 放入结构中。指针是包含地址的数值。当我们这样做时,没有什么神奇的事情发生:
char a[] = "hello";
char* b = a;
b
现在点到a
,字符串仍然只有一份
与此同时,整个代码块似乎很可能会导致此类问题。做以下事情不会让你的生活变得更简单吗:
class Emitter {
std::string name, file;
};
void myFunc() {
metadata.name = atts.getString("name", "ed");
metadata.file = atts.getString("file", "ed");
}
如果这对您不起作用,您可能需要考虑:
const std::string& name = atts.getString("name", "ed");
metadata.name = new char[] (name.length() + 1); // +1 for [=13=]
std::copy(metadata.name, name.c_str());
但请注意,您现在负责delete[]
记忆:
class Emitter {
const char* name;
const char* file;
Emitter() : name(nullptr), file(nullptr) {}
~Emitter() {
if (name)
delete [] name;
if (file)
delete [] file;
}
// ...
};
我有一个罕见的问题。
我已经将结构存储到 std::map,
插入第一个数据并正常运行,但是当我尝试存储多个结构数据时,结构内所有 "seconds" 值的所有 const char*
都丢失了,并被新数据替换。
我恢复代码:
struct Emitter{
.
.
const char * name;
const char * file;
}
Emitter metadata;
在我插入结构之前,我用这段代码填充 const char * 变量(我从 XML 获得信息)
std::string name_tmp= atts.getString("name", "ed");
char tmp[50];
strcpy(tmp, name_tmp.c_str());
metadata.name= tmp;
std::string file_tmp= atts.getString("file", "ed");
char tmp2[50];
strcpy(tmp2, file_tmp.c_str());
metadata.file= tmp2;
地图的key,是Emitter结构体里面的名字;
typedef std::map<std::string, Emitter> Dictionary;
typedef std::pair<std::string, Emitter> Defination;
Dictionary::iterator it = map.find(name);
if (it != map.end())
map[metadata.name] = data;
else{
if (map.size() == 0)
map.insert(Defination(metadata.name, metadata));
else{
ParticlesDictionary::iterator i = map.begin();
map.insert(i, Defination(metadata.name, metadata));
}
}
当我打印插入堆栈输出的过程时,我得到这个:
// key ---> struct value (name) ---> struct value (file)
//first time
key1 --> eddy --> fileName1
//second time
key1 --> eddy1-->fileName2
key2 --> eddy1-->fileName2
//third time
key1 --> eddy2-->fileName3
key2 --> eddy2-->fileName3
key3 --> eddy2-->fileName3
为什么会这样?
请帮忙
您的 const char*
字段指向不属于 struct
的缓冲区。这意味着当数组 tmp
和 tmp2
超出范围时,它们使用的 space 可用于其他数据。
在您的情况下,它会在下一个 struct
中重复使用。要解决此问题,您应该分配 struct
拥有的内存:通过将 const char*
字段替换为 std::string
字段,或使用 new
和 delete
.
无论您是在 SO 上提出问题还是尝试自己解决此类问题,第一步都是构建 MVCE 或 SSCE - 问题的小型离散再现。
使用您的代码,我们将专注于以下方面:
#include <iostream>
struct A {
const char* text;
};
void f(A& a, const char* text) {
char localTxt[50];
strcpy(lt, text);
a.text = localTxt;
}
int main() {
A a, b;
f(a, "hello");
f(b, "world");
std::cout << "But afterwards:" << std::endl;
std::cout << "a = " << a.text << ", b = " << b.text << "\n";
}
我们已经放弃了你在这里所做的大部分工作,并在 "what happens when I put this value into a structure" 上进行了磨练。
而这里的问题是 localText
存在于堆栈中,我们获取了它的地址并将 that 放入结构中。指针是包含地址的数值。当我们这样做时,没有什么神奇的事情发生:
char a[] = "hello";
char* b = a;
b
现在点到a
,字符串仍然只有一份
与此同时,整个代码块似乎很可能会导致此类问题。做以下事情不会让你的生活变得更简单吗:
class Emitter {
std::string name, file;
};
void myFunc() {
metadata.name = atts.getString("name", "ed");
metadata.file = atts.getString("file", "ed");
}
如果这对您不起作用,您可能需要考虑:
const std::string& name = atts.getString("name", "ed");
metadata.name = new char[] (name.length() + 1); // +1 for [=13=]
std::copy(metadata.name, name.c_str());
但请注意,您现在负责delete[]
记忆:
class Emitter {
const char* name;
const char* file;
Emitter() : name(nullptr), file(nullptr) {}
~Emitter() {
if (name)
delete [] name;
if (file)
delete [] file;
}
// ...
};