我只是出于好奇而尝试这个。我有一个带有构造函数和复制构造函数的结构,并尝试使用main中的复制构造函数初始化struct,同时在main中,实现对指向struct的指针的内存分配。复制构造初始化工作正常,但是当我尝试在主返回之前释放它时,它会在堆中导致断言错误。
#include <stdio.h>
#include <malloc.h>
typedef struct tagInfo
{
int iX;
int iY;
tagInfo() {};
tagInfo(int x, int y)
: iX(x), iY(y) {};
~tagInfo() {};
}INFO;
int main (void)
{
INFO* pInfo = (INFO*)malloc(sizeof(INFO));
pInfo = &INFO(10, 10);
free(pInfo);
return 0;
}
如何在不引起断言错误的情况下安全地释放上述指针?
答案 0 :(得分:2)
malloc
和free
不应该在C ++中使用,因为它们不处理对象的构造/破坏。
在现代C ++中,如果要为唯一所有权建模,则应使用std::unique_ptr
;如果要为共享所有权建模,则应使用std::shared_ptr
- 这些被称为&#34;智能指针&#34; ,并提供一种安全的方式来管理动态内存,自动处理释放/销毁。例如:
int main (void)
{
auto pInfo = std::make_unique<INFO>(10, 10);
return 0;
}
如果您真的想要进行手动内存管理,必须使用new
(用于分配+构建)和delete
(用于解除分配) +破坏)。例如:
int main (void)
{
INFO* pInfo = new INFO(10, 10);
delete pInfo;
return 0;
}
答案 1 :(得分:0)
我认为基本的误解是复制构造函数不会将一个对象的内容复制到同一类型的(已存在的)其他对象中,而是生成一个新对象,该对象根据该对象的内容进行初始化。要从中复制的对象。
在您的代码中,使用INFO
为malloc
类型的对象保留内存,并让pInfo
指向该内存。
接下来,使用pInfo = &INFO(10, 10)
在堆栈上(不在堆上)实例化一个INFO类型的新对象,让pInfo
指向该对象的内存地址(在堆栈中) !)。顺便说一句,你放弃了对malloc
- 内存的引用,因为指针pInfo
不再指向malloc
- ed地址,而是指向新对象。
free(pInfo)
至关重要,因为您释放了之前未使用malloc
分配的内存地址。
实际上,您应该执行以下操作:
INFO* pInfo = new INFO(10, 10);
...
delete pInfo;
答案 2 :(得分:0)
一般情况下,您可以使用新的展示位置,但强烈建议不要这样做:
// allocate
void* pInfoMem = malloc(sizeof(INFO));
// construct
INFO* pInfo = new(pInfoMem) INFO(10, 10);
// destruct
pInfo->INFO::~INFO();
// free
free(pInfoMem);
但是你需要在释放之前手动调用析构函数。
这样做更容易(如其他答案所述):
INFO* pInfo = new INFO(10, 10);
delete pInfo;