我有一张地图,可以根据需要填写。为了使地图的内容进入另一个变量,我正在使用memcpy。
如果对memcpy行进行了注释,则可以看到正确显示了输出打印。
100 => 1234水果
如果取消注释memcpy,则会看到以下错误。先前看到的打印也不会显示。
释放两次块
退出:退出失败127
#include <iostream>
#include <map>
#include <string>
struct apple
{
int iValue;
std::string str1;
};
typedef std::map<int, apple> AppleMap;
int main()
{
AppleMap one;
apple structaa;
structaa.iValue = 1234;
structaa.str1 = "Fruits";
int value = 100;
one[value]=structaa;
AppleMap::iterator it = one.find(100);
if(it != one.end())
{
std::cout << it->first << " => " << it->second.iValue << '\t' << it->second.str1 << '\n';
}
else
{
std::cout << "Value Not Found\n";
}
apple structbb;
memcpy(&structbb, &(it->second), sizeof(apple));
return 0;
}
对我做错了什么有帮助吗?
最佳答案
您不能使用apple
复制“深度”结构(例如memcpy
)。您的apple
结构很深的原因是因为它包含一个std::string
,该memcpy
在堆上有内存。当您使用std::string
复制structbb
时,您正在复制指向堆的指针,但是现在您有两个结构(一个structbb
,另一个在映射内指向堆上相同的内存。
正确的做法是直接复制memcpy
而不使用str1
,即
structbb = it->second;
这将使用默认的复制方法,该方法将使用其定义的复制方法复制每个成员。字符串成员
if(it != one.end()
的默认复制方法是安全的,这意味着复制的字符串指向新的堆内存位置,因此可以安全地销毁旧字符串而不影响新字符串。您还将希望将此行移到
it->second
块的保护内。否则,如果得到“找不到值”,则将是伪造的。关于c++ - Memcpy导致块释放两次错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28849304/