c++ - Memcpy 导致 block 释放两次错误

标签 c++ c++11 dictionary std memcpy

我有一张 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/

相关文章:

c++ - 可变递归模板

python - 将键添加到键内已有的值,然后根据键名称添加额外的值和键

c++ - COM:如果我更改接口(interface)的父接口(interface),是否需要创建一个新接口(interface)?

c# - 从 .NET 程序集透明地访问 native 内存

c++ - 为什么声明 `void(*pf)(int) = bar;` 会触发下面代码片段中的 `static_assert`?

c++ - 确保可枚举类型的键/值在软件版本之间永远不会改变

python - 为列表或字典中的每个项目添加年份

python - 当键值直接从字典分配给变量python时函数不起作用

c++ - 在 Mac OSX 中替代 --no-undefined

c++ - 动态增加和减少字符数组?