面试题:malloc用delete会出现什么问题?
这个问题要分情况看,当对象是简单类型时,我测试不会出错
#include <iostream>
int main()
{
int* i = new int[100];
free(i);
char* p = (char*)malloc(100);
delete p;
return 0;
}
在这一份代码示例中,new的内存用free释放, malloc的内存用delete释放,我用VS2022跑了一下是没有报错。原因是 int,float 这种数字类型过于简单,没有复杂的构造/析构函数,因此此时 new 和 malloc在一定程度上是等价的。
虽然这里没有出错,但是不推荐这么写,这么写是否有其他未出现的问题也说不准,因为这么写都可能导致未定义行为。
我们再看一下复杂的类型,例如对象是类类型的:
#include <iostream>
class A
{
public:
A()
{
p = new char(100);
}
~A()
{
delete p;
p = nullptr;
}
private:
char* p = nullptr;
};
int main1()
{
A* pA = (A*)malloc(sizeof(A));
delete pA;
return 0;
}
上面代码示例运行,直接崩溃
类A的指针pA利用malloc生成,malloc不会调用类A的构造函数,所以类A构造函数中的初始化操作 p = new char(100) 不会执行,但是释放的时候调用了delete,delete 会调用类A的析构函数,析构里面做资源清理动作,导致程序崩溃。
对于复杂类型对象:
malloc之后调用delete,不会调用构造函数进行初始化,会调用析构函数进行资源清理。
如果析构函数有资源需要清理,程序会崩溃;如果没有资源清理,程序运行成功。
上面讨论的是malloc和delete混用,那么再看下new和free混用的情况:
#include <iostream>
class A
{
public:
A()
{
p = new char(10000000);
}
~A()
{
delete p;
p = nullptr;
}
private:
char* p = nullptr;
};
int main()
{
A* pA = new A;
free(pA);
return 0;
}
这份代码示例,pA是new出来的,调用了类A的构造函数,但是释放的时候用的free,那么不会调用类A的析构函数。析构函数里面有做资源清理的工作,因为没有调用到析构函数,所以出现了内存泄漏问题。
对于复杂类型对象:
new之后调用free,不会调用析构函数进行资源清理,会调用构造函数进行资源初始化。
如果构造函数有内存资源需要初始化,会导致内存泄漏。
总结:
先malloc后delete,可能导致程序崩溃问题。
先new后free,可能出现内存泄漏问题。
end
CppPlayer
关注,回复【电子书】珍藏CPP电子书资料赠送
精彩文章合集
专题推荐