malloc和free vs new和delete

时间:2015-01-22 23:14:13

标签: c++

您好我读到newdelete优于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()只要在类内的堆上有指针就会导致内存泄漏?

2 个答案:

答案 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;方法,这正是你要做的。