Andre Hofmeister
Andre Hofmeister

Reputation: 3416

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 with 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;.

Upvotes: 1

Views: 400

Answers (4)

Gaim
Gaim

Reputation: 6844

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".

Upvotes: 0

Naszta
Naszta

Reputation: 7734

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

Upvotes: 0

Mihran Hovsepyan
Mihran Hovsepyan

Reputation: 11088

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].

Upvotes: 2

Juraj Blaho
Juraj Blaho

Reputation: 13451

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.

Upvotes: 1

Related Questions