2010-11-27 74 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. 確保您釋放後,你不使用的內存更多的內存。