【问题标题】:Issues understanding heap理解堆的问题
【发布时间】:2011-10-22 23:14:46
【问题描述】:

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

delete[] newChar;

在for循环中:

delete[] newChar[i];

我会这样做:

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

正确吗? newChar[i] 中的内容会发生什么情况?我只是销毁指针,不是吗?

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

【问题讨论】:

  • 更好的是使用std::stringstd::wstring。要将后者转换为前者,请执行std::string s(ws.begin(), ws.end())
  • 现在我像你说的那样做,效果很好。谢谢你。有了这个解决方案,我还可以解决我的内存泄漏问题。谢谢大家!

标签: c++ arrays memory-management heap-memory


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    使用

    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
    

    【讨论】:

      【解决方案3】:

      你做对了,通过operator new[]()分配的内存应该通过operator delete[]()释放。


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

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

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

      【讨论】:

        【解决方案4】:

        拨打delete[] newChar是正确的方法。

        理论上,对于已删除数组中的所有对象/字符,都会调用析构函数。但由于char 是一个原始类型,它什么也不做。无论如何,删除数组后,您不应该访问newChar[i]

        【讨论】:

        • 好的,这将只删除指针还是内存中的所有内容?这可以在解构器中执行,对吗?我必须检查 NULL 吗?
        • @Taz:不,您不必检查 NULL。你可以在你写的析构函数中调用它。
        猜你喜欢
        • 1970-01-01
        • 2011-10-31
        • 2014-08-06
        • 2019-10-16
        • 2021-06-01
        • 2013-05-27
        • 2011-08-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多