操作员删除导致堆损坏,而操作员新工作正常

时间:2010-11-27 06:53:11

标签: c++ new-operator

我有操作员新的工作,但是一旦我调用删除,它就会在free (ptr)行崩溃。在这个Base类中重载operator new和delete时,任何人都可以告诉我做错了什么吗?提示:我不是在询问设计问题。

class Base {
private: 
    int i;

public:  
    Base () : i (10) {
    }

    static void * operator new (size_t size) {  
       if (size = 0) size = 1;  // please read this line carefully! size = 0!
       return malloc (size);  
    }

    static void operator delete (void *ptr, size_t size) {
       if (ptr == NULL) return;
       free (ptr);
    }
};

3 个答案:

答案 0 :(得分:4)

这对我有用:

#include <cstdlib>
using namespace std;
class Base {
public:
    void * operator new(size_t size) {
       if (size == 0) size = 1;
       return malloc (size);
    }

    void operator delete (void *ptr, size_t size) {
       if (ptr == NULL) return;
       free (ptr);
    }
};

int main()
{
    Base* b = new Base;
    delete b;
    return 0;
}

hank@tardis:/tmp$ g++ -o test test.cpp 
hank@tardis:/tmp$ ./test 
hank@tardis:/tmp$ valgrind ./test 
==7229== HEAP SUMMARY:
==7229==     in use at exit: 0 bytes in 0 blocks
==7229==   total heap usage: 1 allocs, 1 frees, 1 bytes allocated
==7229== 
==7229== All heap blocks were freed -- no leaks are possible
==7229== 
==7229== For counts of detected and suppressed errors, rerun with: -v
==7229== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

答案 1 :(得分:2)

实际问题是newdelete运算符都没有。你实现它们非常简单,这里没有问题。

您有堆损坏的实际问题。它是由您的代码引起的,不一定是操纵Base个对象的代码。 只有当你delete你的对象时才会发现堆腐败。

在您delete对象之前,可能有一些代码会发生堆损坏。

您应该检查代码是否存在无效的内存访问。这包括:

  1. 确保您不会访问比分配的内存更多的内存
  2. 确保在释放后不使用内存。

答案 2 :(得分:1)

我发现您提供的示例代码没有任何问题。

以下对我来说很好。

prasoon@prasoon-desktop ~ $ cat leak_check.cpp && g++ leak_check.cpp && valgrind --leak-check=full ./a.out
#include <cstdlib>
class Base {
public:
    static void * operator new (size_t size) {
       if (size == 0) size = 1;
       return malloc (size);
    }

    static void operator delete (void *ptr, size_t size) {
       if (ptr == NULL) return;
       free (ptr);
    }
};

int main()
{
   Base * p = (Base *) Base::operator new(sizeof(Base));
   Base::operator delete((void*)p,sizeof(Base));
}
==4561== Memcheck, a memory error detector
==4561== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==4561== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==4561== Command: ./a.out
==4561== 
==4561== 
==4561== HEAP SUMMARY:
==4561==     in use at exit: 0 bytes in 0 blocks
==4561==   total heap usage: 1 allocs, 1 frees, 1 bytes allocated
==4561== 
==4561== All heap blocks were freed -- no leaks are possible
==4561== 
==4561== For counts of detected and suppressed errors, rerun with: -v
==4561== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 6)

BTW释放空指针完全没问题。

  

free函数导致ptr指向的空间被释放,即可用于进一步分配。如果ptr是空指针,则不会发生任何操作

因此可以省略if (ptr == NULL) return;