Проблемы понимания кучи - PullRequest
1 голос
/ 09 августа 2011

У меня небольшая проблема с кучи в c ++.

Я создал небольшой класс для преобразования Wchar_t-Array в Char-Array.Вот часть моего класса конвертирования:

.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-файле я динамически создаю новый Char-Arrayв куче.Как правильно удалить переменную?Я читал много разных примеров ...

delete[] newChar;

В цикле for:

delete[] newChar[i];

Я бы сделал это так:

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

Это правильно?Что происходит с контентом в newChar[i]?Я просто уничтожаю указатель, не так ли?

Ну, у меня все еще проблема, что произошла утечка памяти, если я использую класс?Как это может быть?Я добавил в свой деконструктор delete[] newChar;.

Ответы [ 4 ]

2 голосов
/ 09 августа 2011

Вы делаете все правильно, выделенные через operator new[]() память должна быть освобождена через operator delete[]().


Но здесь я вижу еще одну проблему:

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

3-й параметр на самом деле не то, что вы хотите. Вы хотите передать размер буфера, но передать количество символов, начиная с первой позиции newChar до первого нулевого символа (см. Руководство по strelen() для более подробной информации). Здесь вам нужно wcslen(WcharArray) + 1 (1 для дополнительного нулевого символа) в качестве 3-го параметра, потому что это реальная длина выделенного фрагмента памяти, который также должен быть выделен new char[wcslen(WcharArray) + 1].

1 голос
/ 09 августа 2011

Вызов delete[] newChar - правильный путь.

Теоретически деструктор будет вызываться для всех объектов / символов в удаленном массиве. Но поскольку char является примитивным типом, он ничего не будет делать. В любом случае, вам не следует обращаться к newChar[i] после удаления массива.

0 голосов
/ 09 августа 2011

Использование

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);

от

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
0 голосов
/ 09 августа 2011

Ваши решения верны.Когда вы вызываете delete [], то блок памяти по указателю устанавливается как свободный, но не более того.Ваш контент будет оставаться там до тех пор, пока вы не выделите другую память в этом блоке адресов и не перезапишете данные.Но вы не можете полагаться на чтение из удаленной памяти.Иногда это работает, но это «случайность».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...