2011-07-19 22 views
3

我會用例子來解釋這個場景。如何刪除在C++的本地函數中創建的對象?

void func() 
    { 
      CLine* pObj = new CLine(); 
    } 
    void func2() 
    { 
    } 

如何刪除func2()中的CLine對象? 這可能嗎?

謝謝

+0

這是有點不清楚什麼是確切的限制是你的要求。 'func'和'func2'的哪些部分可以更改?有很多方法可以做到這一點,這取決於你的代碼可以改變多少。 – Mankarse

回答

13

這是不可能的。只要func完成,你就失去了所有對pObj的引用並泄漏了它的內存。

0

不,這是不可能的。因爲當func超出範圍時,指針的唯一副本將丟失,因此不再需要引用要與operator delete一起使用的內存。

3

在這種情況下,可能根本不需要使用免費商店分配的變量。 只是做:

void func() 
{ 
     CLine obj; 
} 
void func2() 
{ 
} 

obj將在範圍結束時自動銷燬。

如果變量絕對必須是自由分配的店,那麼你可以把它放在一個的unique_ptr如下:

void func() 
{ 
     const std::unique_ptr<CLine> obj(new CLine()); 
} 
void func2() 
{ 
} 

如果您使用c++03然後只是auto_ptr取代unique_ptr

無論如何,如果你真的必須使用完全相同的代碼,因爲它是在你的例子則有辦法還是刪除CLine對象。你必須使用重載的operator new和operator delete。它必須是這樣的:

#include <vector> 
#include <new> 
#include <algorithm> 
struct CLine { 
    //... Other members ... 

    static std::vector<void*> pointerCache; 

    void* operator new(std::size_t size) throw(std::bad_alloc) { 
     while (true) { 
      void* pointer(malloc(size)); 
      if (pointer) { 
       try { 
        pointerCache.push_back(pointer); 
        return pointer; 
       } 
       catch (std::bad_alloc&) { 
        free(pointer); 
       } 
      } 
      if (std::new_handler handler = std::set_new_handler(0)) { 
       std::set_new_handler(handler); 
       (*handler)(); 
      } 
      else { 
       throw std::bad_alloc(); 
      } 
     } 
    } 

    void operator delete(void *p) throw() { 
     pointerCache.erase(std::remove(pointerCache.begin(), pointerCache.end(), p),pointerCache.end()); 
     free(p); 
    } 

    void* operator new(std::size_t size, std::nothrow_t const&) throw() { 
     try { 
      return operator new(size); 
     } catch (std::bad_alloc&) { 
      return 0; 
     } 
    } 
    //Compressed for space constraints. 
    void operator delete(void *p, std::nothrow_t const&) throw(){ 
     operator delete(p);} 
    void* operator new[](std::size_t size) throw(std::bad_alloc){ 
     return operator new(size);} 
    void operator delete[](void *p) throw(){operator delete(p);} 
    void* operator new[](std::size_t size, std::nothrow_t const& nothrow) throw(){ 
     return operator new(size, nothrow);} 
    void operator delete[](void *p, std::nothrow_t const& nothrow) throw(){ 
     operator delete(p, nothrow);} 
}; 
std::vector<void*> CLine::pointerCache; 

然後你的代碼看起來是這樣的:

void func() 
{ 
    CLine* pObj = new CLine(); 
} 
void func2() 
{ 
    //The most recently added pointer in CLine::pointerCache is 
    // the one that was added in func() 
    delete static_cast<CLine*> (CLine::pointerCache.back()); 
} 

int main() 
{ 
    func(); 
    func2(); 
}  

不過說真的,有這麼多的錯誤與此代碼,你會得到更好的只是更改設計。其中一些問題包括:您會讓人們閱讀您的代碼時感到困惑,缺乏線程安全性以及使用全局對象。

1

如果func()和func2()是同一個類的方法,並且pObj是該類的成員變量,那麼這是可能的。我意識到這不是你如何構建你的問題,但這是獲得你正在尋找的效果的一種方法

class MyClass 
{ 
    CLine* pObj; 

    void func() 
    { 
      pObj = new CLine(); 
    } 
    void func2() 
    { 
     delete pObj; 
    } 
} 
1

是的,你可以。

void func() 
{ 
    CLine* pObj = new CLine(); 
} 

void func2(CLine* pObj) 
{ 
    delete pObj; 
} 

如果你通過克萊恩指針FUNC2

0

你必須刪除你在函數本身內部函數動態創建的對象。如果您在不刪除該功能的情況下離開該功能,則無法將其刪除並且內存丟失。

相關問題