您好我读到new
和delete
优于malloc()
和free()
,因为free()
在delete
时没有调用析构函数不...
例如:
#include <iostream>
using namespace std;
class String
{
public:
String();
String(const String&){cout<<"String cpy ctor\n";}
~String();
private:
int* itsParray;
};
String::String()
{
cout<<"String ctor\n";
itsParray=new int[100];
for(int i(0);i<100;i++)
itsParray[i]=i+1;
}
String::~String()
{
cout<<"String dtor\n";
delete[] itsParray;
itsParray=NULL;
}
int main()
{
String* pStr=NULL;
pStr = static_cast<String* > (malloc(4 * sizeof(String)));
free(pStr);
pStr=new String[4];
delete[] pStr;
cout<<endl<<endl<<endl;
return 0;
}
当我执行程序时,我看到在String
上调用delete
时调用了四个pStr
对象的析构函数。但由free()
删除的四个不会调用析构函数。这是否意味着free()
只要在类内的堆上有指针就会导致内存泄漏?
答案 0 :(得分:5)
new
调用构造函数,malloc()
不调用。 delete
调用析构函数,free()
不调用析构函数。如果有问题的类在内部分配内存,那么是的,您可能会遇到内存泄漏。
如果您必须使用malloc()
和free()
(在C ++中,您真的不应该这样做),则必须使用展示位置来调用构造函数,并自己调用析构函数,例如:
pStr = static_cast<String*>(malloc(4 * sizeof(String)));
if (pStr)
{
for (int i = 0; i < 4; ++i)
new (&pStr[i]) String;
...
for (int i = 3; i >= 0; --i)
pStr[i].~String();
free(pStr);
}
如果你真的需要模仿new[]
,你应该处理构造函数抛出的异常,例如:
pStr = static_cast<String*>(malloc(4 * sizeof(String)));
if (!pStr)
throw std::bad_alloc("");
int numConstructed = 0;
try
{
for (int i = 0; i < 4; ++i)
{
new (&pStr[i]) String;
++numConstructed;
}
}
catch (const std::exception &)
{
for (int i = numConstructed-1; i >= 0; ++i)
pStr[i]).~String();
throw;
}
...
for (int i = numConstructed-1; i >= 0; --i)
pStr[i].~String();
free(pStr);
答案 1 :(得分:0)
是。对于C ++对象,您必须使用&#39; new&#39;并且&#39;删除。&#39; &#39;新&#39;将确保调用对象的构造函数,并删除&#39;将确保调用对象的析构函数。
malloc()和free()是内存分配例程(来自C世界),但不会调用构造函数或析构函数。如果这些对象本身(在构造函数中或在其生命周期内)分配内存,可能析构函数将取消分配该内存,但为了确保发生这种情况,您必须使用&#39; delete&#39;这样就可以调用析构函数。
另外,不要将new / delete与malloc / free混合使用。也就是说,不要使用新的&#39;然后是同一个对象上的free(),或者一个malloc(),然后是&#39; delete。&#39;它不会工作。
仅供参考,&#39;新&#39;可以用malloc()实现,然后调用一个对象的构造函数。 &#39;删除&#39;可以在调用对象的析构函数之后以free()的形式实现。事实上,如果你写一些特定类别的新的&#39;并且&#39;删除&#39;方法,这正是你要做的。