2012-03-13 153 views
0

考慮下面的代碼片段誰負責釋放分配的內存?

void xyz(CString **mapping) 
{ 
    *mappings = new CString[10]; 
    (*mappings)[0] = "hello"; 
    //... 
} 

void main(int argc, char **argv) 
{ 
    CString *tmp; 
    xyz(&tmp); 
    // now we have the CString array defined in xyz 
} 

我想要做的是,以填補因主峯的VAR與由另一個函數生成一些值。我讀了它的最佳做法,即刪除/釋放與分配的功能相同的功能。這在這種情況下是不可能的,因爲xyz存在的唯一原因是生成數據(這僅僅是一個例子,在實際情況下,在xyz ;中會有更多複雜性))。我也考慮在main中的堆棧上創建一個數組,並將它傳遞給函數,但在我的情況下,數組的大小在當時不是固定的(它在xyz中確定)。清理分配內存的最乾淨和最常用的方法是什麼? 如果我們有方法xyz的對象,那麼最佳實踐是什麼?要創建另一個方法(例如freeMapping()),在處理數據後必須由調用方調用?

+4

C或C++,決定。因爲在C++中,你只需使用'std :: vector'。 – 2012-03-13 23:04:05

+3

如果您正在研究C++,那麼將分配的數據包裝到一個對象中,該對象在超出範圍時釋放內存。 – Tony 2012-03-13 23:04:09

+0

上次編輯將問題從C++改爲C,這會使答案失效。如果您有新問題,請在網站上進行搜索,如果失敗(不會),請提出新問題。 – 2015-05-11 18:29:07

回答

0

這是你在這裏展示的不良做法。所以它有2個解決方案:

  1. 在主函數中分配和釋放內存。

  2. 創建一個類,它將負責該字符串的所有操作並在主函數中使用它。

0

的RAII風格類(即釋放的對象在其析構函數的包裝)是處理這種事情的常用方法(見的std :: auto_ptr的或一些更現代的替代品,如boost ::的scoped_ptr或std :: unique_ptr)。當auto_ptr/unique_ptr超出範圍時,會自動調用delete。

傳入對調用程序堆棧上創建的std :: vector的引用可能有效。

通過值返回一個std :: vector很容易理解,並且可以根據您的要求很好地執行。

+0

RAII不僅僅是一個包裝資源的資源,它可以釋放dtor中的資源。智能指針也不是獨立於RAII的;他們使用RAII來實現擁有不同所有權語義的指針。 – bames53 2012-03-14 00:21:50

1

有許多不同的方案,人們使用多年來,有些更好或更糟。良好的策略定義了一個嚴格一致的模式,爲資源的「所有權」制定了規則,即清理責任和確保沒有任何資源非法訪問資源。成功策略的規則也是這樣的,只有對資源的本地視圖以及如何使用纔是安全訪問資源的必要條件。

您應該在現代C++中使用的策略稱爲RAII或「資源獲取是初始化」。這個名字意味着任何獲得的資源都應該是一個初始化。例如:

std::string s = "Hello, World"; 

此代碼獲取一些內存作爲存儲字符串數據的資源,但您看到的只是該字符串已初始化。被初始化的對象擁有內存。這意味着它負責管理內存的使用期限並限制對內存的訪問。使用該對象的代碼根本不需要考慮資源。只需確保它正確使用對象本身,並且隱藏資源的生命週期將依次正確管理。

使用RAII不僅方便了本地資源的正常管理,而且在出現異常情況下也大大簡化了資源的正確清理工作。當範圍由於異常而退出時,C++保證銷燬該範圍內的所有完全構造的對象。如果清理資源的必要任務是由對象析構函數完成的,那麼資源不會泄漏,並且不需要將明確的異常處理添加到使用資源的每個範圍。

C++已經包含了許多類型資源的資源擁有類。對於動態調整大小的陣列使用std::vector

std::vector<CString> xyz() 
{ 
    // C++11 
    return {"hello",...}; 

    // or C++03 
    std::vector<CString> mappings; 
    mappings.push_back("hello"); 
    ... 
    return mappings 
} 

void main(int argc, char **argv) 
{ 
    std::vector<CString> tmp = xyz(); 
    // now we have the CString array defined in xyz 
    // the array gets automatically cleaned up by std::vector's destructor 
}