Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
理解堆的问题 我在C++中有一个小的理解问题。_C++_Memory Management_Heap_Arrays - Fatal编程技术网

理解堆的问题 我在C++中有一个小的理解问题。

理解堆的问题 我在C++中有一个小的理解问题。,c++,memory-management,heap,arrays,C++,Memory Management,Heap,Arrays,我创建了一个小类来将Wchar_t-Array转换为Char数组。以下是我的convert类的一部分: h .cpp 在Cpp文件中,我在堆中动态创建一个新的字符数组。 如何正确删除变量?我读了很多不同的例子 delete[] newChar; 在for循环中: delete[] newChar[i]; 我想这样做: ~ConvertDataType(void) //deconstructor { delete[] newChar; } 对吗?newChar[i]中的内容会发生什么变化?我

我创建了一个小类来将Wchar_t-Array转换为Char数组。以下是我的convert类的一部分:

h

.cpp

在Cpp文件中,我在堆中动态创建一个新的字符数组。 如何正确删除变量?我读了很多不同的例子

delete[] newChar;
在for循环中:

delete[] newChar[i];
我想这样做:

~ConvertDataType(void) //deconstructor
{
delete[] newChar;
}
对吗?
newChar[i]
中的内容会发生什么变化?我只是破坏了指针,不是吗

好吧,我仍然有一个问题,那就是如果我使用这个类,内存泄漏会发生吗?
怎么可能呢?我在解构器中添加了
delete[]newChar

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


理论上,将为已删除数组中的所有对象/字符调用析构函数。但是由于
char
是一种基本类型,因此它将不起任何作用。无论如何,在删除阵列后,您不应访问
newChar[i]

如果操作正确,则应通过
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[]
时,内存块refereby pointer设置为free,但仅此而已。在您在此地址块中分配另一个内存并覆盖数据之前,您的内容仍将存在。但你不能依赖于从删除的内存中读取。有时它可以工作,但这是“一个意外”。

使用

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上,我将使用进行转换:

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

好的,这会只删除指针还是删除内存中的所有内容?这可以在解构器中执行,对吗?我必须检查空值吗?@Taz:不,你不必检查空值。您可以在编写时在析构函数中调用它。更好的方法是使用
std::string
std::wstring
。要将后者转换为前者,请执行std::string s(ws.begin(),ws.end())。现在,我按照u所说的那样执行,效果非常好。非常感谢。使用此解决方案,我还可以修复内存泄漏问题。谢谢大家!
char *newChar = new char[wcslen(WcharArray)];
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