我有一张 map ,我正在根据需要进行填充。为了将 map 的内容输出到另一个变量中,我使用了 memcpy。
如果 memcpy 行被注释,我会看到正确显示的输出打印。 100 => 1234 个水果
如果我取消对 memcpy 的注释,我会看到以下错误。之前看到的打印品也不会显示。
block 释放两次
退出:ExitFailure 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;
}
对我做错了什么有什么帮助吗?
最佳答案
您不能使用memcpy
复制“深层”结构(例如apple
)。你的 apple
结构很深的原因是因为它包含一个 std::string
,它在堆上有内存。当您使用 memcpy
复制 std::string
时,您正在复制指向堆的指针,但现在您有两个结构(一个 structbb
和映射中的一个指向堆上的同一内存。
正确的做法是直接复制structbb
,不要使用memcpy
,即
structbb = it->second;
这将使用默认的复制方法,该方法将使用他们定义的复制方法复制每个成员。字符串成员str1
的默认复制方法是安全的,意味着复制的字符串指向一个新的堆内存位置,这样旧的字符串可以安全销毁而不影响新字符串。
您还需要将此行移到您的 if(it != one.end()
block 的保护范围内。否则,如果您收到“未找到值”,it->second
将是伪造的。
关于c++ - Memcpy 导致 block 释放两次错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28849304/