2013-08-28 101 views
1

我想刪除舊的應用程序的所有刪除和刪除[],並使用智能指針。在下面的代碼片段中,我想刪除最後一個cicle。刪除刪除/刪除[]

std::unique_ptr<MapiFileDesc> fileDesc(new MapiFileDesc[numFiles]); 

for (int i = 0; i < numFiles; ++i) 
{ 
    // Works but I've to delete[] at the end 
    fileDesc[i].lpszPathName = new CHAR[MAX_PATH]; 

    // Does not work. For each iteration the previous array will be deleted 
    // It also happens with shared_array 
    boost::scoped_array<CHAR> pathName(new CHAR[MAX_PATH]); 
    fileDesc[i].lpszPathName = pathName.get(); 
} 

// I want to remove the following cicle 
for (int i = 0; i < numFiles; ++i) 
{ 
    delete [] fileDesc[i].lpszPathName; 
    fileDesc[i].lpszPathName = nullptr; 
} 

你認爲它是造成這種情況的最佳方法:使用包裝對象,將跟蹤創建的所有陣列,並在析構函數刪除或使用boost :: shared_array的載體和分配他們對每個元素?

std::vector<boost::shared_array<CHAR> > objs; 

for (int i = 0; i < 10; ++i) 
{ 
    objs.push_back(boost::shared_array<CHAR>(new CHAR[MAX_PATH])); 
} 

我需要的,因爲我使用VC++ 2008

在此先感謝使用boost :: shared_ptr的。 J.拉塞爾達

+15

使用'std :: string'。 – Fanael

+1

如果您使用'new []'進行分配,則需要'std :: unique_ptr '。但是,使用'std:string'代替。 – juanchopanza

+0

@juanchopanza只是爲了好奇,這是C++ 11的唯一語法,還是它可以和(舊的)std :: auto_ptr一起正常工作呢? –

回答

10
std::vector<std::string > objs(numFiles, std::string(MAX_PATH, 0)); 
std::vector<MapiFileDesc> fileDesc(numFiles); 
for (int i = 0; i < numFiles; ++i) 
    fileDesc[i].lpszPathName=objs[i].data(); 
// after the C API calls, if you do need to use the strings as C++ strings, 
// resync the C++ string length with the C string data 
// (not necessary if you just use them via c_str()) 
for (int i = 0; i < numFiles; ++i) 
    objs[i].resize(strlen(objs[i].c_str()); 

順便說一句,如果你並不需要通過整個數組到C API,但只是單一的結構,可以使存儲兩個MapiFileDesc結構和std::string一個結構單一的載體,結合強烈的兩個對象的生命週期,並允許構造函數負責連接lpszPathName與字符串data()成員;如果這種結構只用於單一功能,可能我也不打擾。

+0

對於實際提供具體解決方案的答案:) – LihO

1
std::unique_ptr<MapiFileDesc[]> fileDesc(new MapiFileDesc[numFiles]); 
typedef std::unique_ptr<CHAR[]> CharBuffer; 
std::vector<CharBuffer> pathNameBuffers; 

for (int i = 0; i < numFiles; ++i) 
{ 
    pathNameBuffers.push_back(CharBuffer(new CHAR[MAX_PATH])); 
    fileDesc[i].lpszPathName = pathNameBuffers.back().get(); 
} 

這不空出末尾的指針雖然。

+0

但是它會在功能終止時釋放分配的內存,對吧? – javlacerda

+0

是的,'pathNameBuffers'超出了範圍。 (說到這一點,如果可能的話,應該在*'fileDesc'之前聲明*,以便字符串比指針長。) –

1

在嘗試減少指針數量/擺脫醜陋的內存管理時,減少調用deletedelete[]的數量並不是您可以做的唯一的事情。

標準庫提供了許多整潔的類,使您可以使用具有自動存儲持續時間的對象。使用STL容器(如std::vector)代替C風格的數組以及用於語義表示字符串的字符數組,相應地使用std::stringstd::wstring

0

我喜歡boost共享數組的方法。我認爲我面臨的問題是boost()中的get()方法shared_array不會增加對象的引用計數。這裏有一個在你的例子中將增加引用計數的工作。

for (int i = 0; i < numFiles; ++i) 
{ 
    // Works but I've to delete[] at the end 
    fileDesc[i].lpszPathName = new CHAR[MAX_PATH]; 

    // Does not work. For each iteration the previous array will be deleted 
    // It also happens with shared_array 
    boost::shared_array<CHAR> pathName(new CHAR[MAX_PATH]); 
    fileDesc[i].lpszPathName = pathName.get(); 

    **// Here is a workaround to increase reference count 
    boost::shared_array<CHAR> pathNameTemp (pathName);** 
} 
+0

循環結束後,引用計數將會是一個和fileDesc被摧毀的內存將被刪除。 – ptrehan