2011-08-09 25 views
1

我對C++中的堆有一個小的理解問題。我創建了一個小類來將Wchar_t數組轉換爲Char數組。這裏是我的轉換類的一部分:理解堆的問題

.H

class ConvertDataType 
{ 
private: 
    char *newChar; 
}; 

的.cpp

size_t i; 
char *newChar = new char[wcslen(WcharArray)]; 
wcstombs_s(&i, newChar, strlen(newChar), WcharArray, wcslen(WcharArray)); 
return newChar; 

在CPP-文件I動態在堆中創建一個新的字符數組。 如何正確刪除變量?我看了很多的不同,例子...

delete[] newChar; 

在for循環:

delete[] newChar[i]; 

我會做這樣的:

~ConvertDataType(void) //deconstructor 
{ 
delete[] newChar; 
} 

是正確的嗎? newChar[i]中的內容會發生什麼情況?我只是摧毀指針,不是嗎?

那麼,我仍然有問題,如果我使用類,發生內存泄漏? 這怎麼可能?我加入了我的解構器delete[] newChar;

+1

更好的是使用'std :: string'和'std :: wstring'。要將後者轉換爲前者,請執行'std :: string s(w​​s.begin(),ws.end())'。 –

+1

現在我就像你說的那樣做,它運作得非常好。謝謝。有了這個解決方案,我也可以修復我的內存泄漏問題。感謝大家! – hofmeister

回答

0

您的解決方案是正確的。當你調用delete []時,通過指針指向的內存塊被設置爲空閒,但僅此而已。直到您在此地址塊中分配另一個內存並覆蓋數據之前,您的內容仍將保留在那裏。但是你不能依賴從已刪除的內存中讀取數據。有時它有效,但它是「一個意外」。

1

調用delete[] newChar是正確的方法。

理論上,析構函數將被調用,用於刪除數組中的所有對象/字符。但由於char是一種原始類型,它什麼都不會做。無論如何,在刪除陣列後,您不應該訪問newChar[i]

+0

好的,這是否會刪除指針或內存中的所有東西?我可以在解構器中執行,對吧?我必須檢查NULL嗎? – hofmeister

+0

@Taz:不,你不必檢查NULL。你可以在你寫的析構函數中調用它。 –

2

你做的事情是正確的,通過operator new[]()分配內存應該通過operator delete[]()釋放。


但在這裏我看到了另一個問題:

wcstombs_s(&i, newChar, strlen(newChar), WcharArray, wcslen(WcharArray)); 

第三個參數實際上是不是你想要的。您想傳遞緩衝區的大小,但要傳遞從newChar的第一個位置開始的字符數,直到第一個空字符(有關更多詳細信息,請參見strelen()的手冊)。這裏你需要wcslen(WcharArray) + 1(1表示額外的空字符)作爲第三個參數,因爲它是分配的內存塊的實際長度,它也應該由new char[wcslen(WcharArray) + 1]分配。

0

使用

size_t new_size = wcslen(WcharArray); 
size_t number_of_converted = 0; 
this->newChar = new char[new_size]; 
wcstombs_s(&number_of_converted, this->newChar, new_size, WcharArray, new_size); 

insted的的

char *newChar = new char[wcslen(WcharArray)]; 

在第二種情況下,你讓一個局部變量。在Windows上,我將使用WideCharToMultiByte進行轉換:

DWORD mb_size = WideCharToMultiByte(
    CP_UTF8, // UTF-8 encoding 
    0,   // flags 
    WcharArray, // wide char input 
    -1,   // find the end of string 
    NULL,  // no input, we want to know the necessary space 
    NULL,  // no input size 
    NULL,  // no default chars 
    NULL);  // no used default chars 
this->newChar = new char[mb_size]; 
mb_size = WideCharToMultiByte(
    CP_UTF8, // UTF-8 encoding 
    0,   // flags 
    WcharArray, // wide char input 
    -1,   // find the end of string 
    this->newChar, // target string 
    mb_size,  // target string size 
    NULL,  // no default chars 
    NULL);  // no used default chars