开发者

Issues understanding heap

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜