我有一张地图,可以根据需要填写。为了使地图的内容进入另一个变量,我正在使用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/

10-13 08:25