I have a small understanding problem with the heap in c++.
I have created a small class to convert a Wchar_t-Array to a Char-Array. Here is a part of my convert class:
.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;
In the Cpp-File I create dynamically a new Char-Array in the Heap. How do correctly delete the variable? I read a lot of different, examples…
delete[] newChar;
In a for loop:
delete[] newChar[i];
I would do it like:
~ConvertDataType(void) //deconstructor
{
delete[] newChar;
}
Is that correct? What happens 开发者_如何学Cwith the content in newChar[i]
? I just destroy the pointer, isn't it?
Well, I have still the problem, that a memory leak happened, if I use the class?
How could that be? I added to my deconstructor delete[] newChar;
.
You do things correct, allocated via operator new[]()
memory should be deallocated via operator delete[]()
.
But here I see another problem:
wcstombs_s(&i, newChar, strlen(newChar), WcharArray, wcslen(WcharArray));
3rd parameter actually is not what you want. You want to pass size of buffer but passing number of characters starting from first position of newChar
until first null-character (see manual of strelen()
for more details). Here you need wcslen(WcharArray) + 1
(1 for extra null-character) as 3rd parameter because it is the real length of allocated memory chunk which also should be allocated by new char[wcslen(WcharArray) + 1]
.
Calling delete[] newChar
is the correct way.
Theoretically destructor will be called for all objects/characters in the deleted array. But as char
is a primitive type it will do nothing. Anyway you should not access the newChar[i]
, after you delete the array.
Your solutions is correct. When you call delete []
then the memory block refer by pointer is set as free but nothing more. Your content will still be there until you allocate another memory in this address block and you overwrite the data. But you cannot rely on reading from deleted memory. Sometimes it works but it is "an accident".
Use
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 of
char *newChar = new char[wcslen(WcharArray)];
In second case you make a local variable. On Windows I would use WideCharToMultiByte to make the conversion:
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
精彩评论