2010-11-27 92 views
5

我已经得到运营商新的工作,但只要我呼吁删除,它崩溃在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); 
    } 
}; 
+1

你们是不是要删除对象两次或删除通过指针不调用`new`获得的对象? – 2010-11-27 06:57:43

+0

作为一个方面说明,`free(NULL)`保证是安全的(一个无操作),所以你不必特殊情况。 – 2010-11-27 07:14:57

回答

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; 
} 

[email protected]:/tmp$ g++ -o test test.cpp 
[email protected]:/tmp$ ./test 
[email protected]:/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

我看不出有什么问题,你给的示例代码。

以下工作适合我。

[email protected] ~ $ 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) 

顺便说一句,释放空指针是非常好的。

free功能使空间指向ptr被解除分配,即,提供用于进一步的分配。如果ptr是空指针,则不会发生动作

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

2

实际的问题是没有new也没有delete运营商。你的实现非常简单,这里没有问题。

您遇到的实际问题为堆损坏。这是由您的代码造成的,不一定是操纵Base对象的代码。 这只是当你的对象delete正好发现堆损坏。

也许你有一些代码在你的对象delete之前确实堆腐败。

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

  1. 确保你不访问除分配
  2. 确保您释放后,你不使用的内存更多的内存。