使用内存复制对象时出现双自由或损坏错误
double free or corruption error when copying object with memcpy
我有以下代码:
#include <iostream>
#include <string>
#include <cstring>
struct test {
std::string name;
size_t id;
};
int main() {
test t;
t.name = "147.8.179.239";
t.id = 10;
char a[sizeof(t)] = "";
std::memcpy(a, &t, sizeof(t));
test b;
std::memcpy(&b, a, sizeof(t));
std::cout << b.name << " " << b.id << std::endl;
}
当我编译并运行它时,它给了我以下错误:
147.8.179.239 10
*** Error in `./test': double free or corruption (fasttop): 0x0000000000bf9c20 ***
Aborted (core dumped)
结果证明代码可以打印出结果。但是我该如何修复这个错误呢?
按您的方式使用memcpy
,您有两个完全相同的std::string
对象。这包括它们可能在内部使用的任何指针。因此,当每个对象的析构函数运行时,它们都试图释放同一个指针。
这就是为什么你需要使用复制构造函数或将一个分配给另一个(即使用覆盖的operator=
)。它知道这些实现差异并正确处理它们,即为目标对象分配一个单独的内存缓冲区。
如果要提取std::string
中包含的字符串,则需要将对象序列化为已知的表示形式。然后你可以反序列化来转换它。
std::string s1 = "hello";
printf("len=%zu, str=%sn",s1.size(),s1.c_str());
// serialize
char *c = new char[s1.size()+1];
strcpy(c, s1.c_str());
printf("c=%sn",c);
// deserialize
std::string s2 = c;
printf("len=%zu, str=%sn",s2.size(),s2.c_str());
对其他类对象执行类似的步骤
您不能像test
那样memcpy()
非pod结构体。你完全破坏了std::string
成员。
必须使用复制构造函数来复制c++对象。
你得到一个双自由错误的实际原因是固定的事实,而不是为你的变量a
和b
创建一个新的字符串对象,你只是复制引用(string
对象是使用可变长度char *
实现的)。
由于string
析构函数在程序结束时释放了这个内存地址,并且如上所述,有两个字符串对象指向同一个地址,因此会得到一个双自由度错误
这将工作,就像@JesperJuhl说的,你必须使用复制构造函数
#include <iostream>
#include <string>
#include <cstring>
struct test
{
std::string name;
size_t id;
};
int main()
{
test t;
test a;
test b;
t.name = "147.8.179.239";
t.id = 10;
a=t;
b=t;
std::cout << b.name << " " << b.id << std::endl;
}
相关文章:
- 为什么会发生堆损坏
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 平均图像时图像损坏
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 将自由函数绑定为类成员函数
- 为什么C中的通用链表中存储的数据已损坏
- 使用GDB修复大型项目中的双自由或损坏(!prev)错误
- Sqlite3和pthread,双自由或损坏(out)
- 双自由或由矢量引起的损坏
- 双自由或损坏(fasttop):0x000000000063d070***c++sive程序
- c++双自由或损坏(fasttop)--不确定错误在哪里
- C 用向量序列化对象会导致双重自由损坏
- glibc在运行C++代码时检测到*双自由或损坏错误
- 如何避免拷贝赋值操作符的双重自由或损坏(fasttop)
- 双重自由或损坏:c++
- 错误:双重自由或损坏(fasttop) -由析构函数引起,但如何
- c++:双重自由或损坏(fasttop)
- 使用内存复制对象时出现双自由或损坏错误
- 删除引用时的双重自由或损坏
- queue::push后的双重自由或损坏