c++中std::map中的Const char *重复数据
const char * duplicate data inside of std::map in c++
我有一个罕见的问题。
我把一个struct存储到std::map中,插入第一个数据并正常运行,但是当我试图存储多个结构体数据时,所有"秒"值的所有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;
映射的键,是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));
}
}
当我打印insert堆栈输出的过程时,我得到这个:
// 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
超出作用域时,它们使用的空间可用于其他数据。
在您的情况下,它被重用为下一个struct
。要解决这个问题,应该分配由struct
拥有的内存:要么用std::string
字段替换const char*
字段,要么使用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";
}
我们已经抛弃了你在这里所做的大部分事情,并专注于"当我将这个值放入结构中时会发生什么"。
这里的问题是localText
存在于堆栈上,我们取了它的地址并把放入结构体中。指针是一个包含地址的数值。当我们这样做的时候,没有什么神奇的事情发生:
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
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;
}
// ...
};
相关文章:
- 使用 char* 存储数据和产生的错误
- 将传入的网络"char*"数据转换为"uint8_t"并返回的安全方法是什么?
- 有效地将数据加载到 std::vector 中<char>
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- 如何正确使用 fstream 并在 char 数组中传递数据?
- 从带有 std::ifstream::read() 的文件中读取 int 遍历 char * 二进制数据
- Arduino 无法匹配 Char 数据
- 访问时 Char* 数据会发生变化
- 如何将OpenCV垫子转换为JPEG CHAR数据
- 将JPEG CHAR数据转换为OpenCV垫子
- 如何将char数据附加到std :: vector而不会导致副本
- 如何在忽略 null 的同时将数据从 char [] 复制到常量字符 *
- 缓冲区用不需要的数据填充 char 数组中的最后一个空格
- 从循环返回char函数数据
- 预安装库中的常见数据类型(Int、Char 等)大写
- 将数据从 vector<unsigned char> 传输到无符号 char[]
- 将包含位字段和动态数据的结构复制到 Char 数组缓冲区中
- 如何使用boost.asio读取整个Char类型的数据
- 数据结构对齐:为什么Char和STD :: String的数组不同
- Python如何通过SWIG从c++获取二进制数据(char*)