问题理解堆

Issues understanding heap

本文关键字:问题      更新时间:2023-10-16

我对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-File中,我动态地在堆中创建了一个新的Char-Array。如何正确删除变量?我读了很多不同的例子……

delete[] newChar;

for循环:

delete[] newChar[i];

我想这样做:

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

正确吗?newChar[i]中的内容会发生什么变化?我只是破坏了指针,不是吗?

好吧,我仍然有问题,内存泄漏发生,如果我使用类?这怎么可能呢?我添加了解构器delete[] newChar;

你做的事情是正确的,通过operator new[]()分配的内存应该通过operator delete[]()释放。


但是这里我看到了另一个问题:

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

第三个参数实际上不是您想要的。您想要传递缓冲区的大小,但从newChar的第一个位置开始传递字符数,直到第一个空字符(请参阅strelen()的手册了解更多细节)。这里需要wcslen(WcharArray) + 1(1表示额外的空字符)作为第三个参数,因为它是分配的内存块的实际长度,也应该由new char[wcslen(WcharArray) + 1]分配。

调用delete[] newChar才是正确的方法。

理论上,对于被删除数组中的所有对象/字符都将调用析构函数。但是由于char是一个基本类型,它将不做任何事情。无论如何,在删除数组之后,您不应该访问newChar[i]

你的解决方案是正确的。当你调用delete []时,由指针引用的内存块被设置为空闲,但仅此而已。您的内容将仍然存在,直到您在此地址块中分配另一个内存并覆盖数据。但是不能依赖于从已删除的内存中读取。

使用

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