C++;内存-使用';新';需要删除吗? 对于C++中的内存管理,我有点新。我了解到,如果使用new关键字创建一个类,则必须删除该对象以释放其内存。我还了解到,基本类型(如int、char和bool)是在堆栈上创建的,这意味着它们在超出范围时会被删除
但使用C++;内存-使用';新';需要删除吗? 对于C++中的内存管理,我有点新。我了解到,如果使用new关键字创建一个类,则必须删除该对象以释放其内存。我还了解到,基本类型(如int、char和bool)是在堆栈上创建的,这意味着它们在超出范围时会被删除,c++,winapi,memory,memory-management,allocation,C++,Winapi,Memory,Memory Management,Allocation,但使用new关键字创建的基本类型呢?是否需要显式调用delete?这些是在堆上创建的类吗?或者,由于它们是基本的,它们仍然在堆栈上创建吗 我这样问是因为我正在使用new关键字分配一个LPTSTR,但我担心如果我不调用delete,内存将永远不会被释放。下面是我的代码,注释中有一个简单的问题: #include <Windows.h> #include <tchar.h> #include <string> #ifdef _UNICODE typede
new
关键字创建的基本类型呢?是否需要显式调用delete
?这些是在堆上创建的类吗?或者,由于它们是基本的,它们仍然在堆栈上创建吗
我这样问是因为我正在使用new关键字分配一个LPTSTR
,但我担心如果我不调用delete
,内存将永远不会被释放。下面是我的代码,注释中有一个简单的问题:
#include <Windows.h>
#include <tchar.h>
#include <string>
#ifdef _UNICODE
typedef std::wstring Str;
#else // ANSI
typedef std::string Str;
#endif
Str GetWndStr(HWND hwnd) {
const int length = GetWindowTextLength(hwnd);
if (length != 0) {
LPTSTR buffer = new TCHAR[length + 1]; // Allocation of string
GetWindowText(hwnd, buffer, length + 1);
Str text(buffer);
delete buffer; // <--- Is this line necessary?
return text;
} else {
return _T("");
}
}
#包括
#包括
#包括
#ifdef_UNICODE
typedef std::wstring Str;
#else//ANSI
typedef std::string Str;
#恩迪夫
Str GetWndStr(HWND-HWND){
const int length=GetWindowTextLength(hwnd);
如果(长度!=0){
LPTSTR buffer=new TCHAR[length+1];//字符串的分配
GetWindowText(hwnd,缓冲区,长度+1);
Str文本(缓冲区);
删除缓冲区;//是(除非您使用智能指针或类似工具为您删除它)当然,无论分配的是什么类型。它仍然有内存空间。是的,规则非常简单。使用新建分配的所有内容都需要处理删除;使用新建[]
需要解除分配删除[]
为了减少出错的机会,最好使用容器、智能指针或其他样式的对象来管理动态资源,而不是记住自己使用delete
。对于每一个新的必须有一个delete
,对于每一个新的[]
必须有一个delete[]
。请注意,分配给new[]
的内存必须使用delete[]
删除,这在发布的代码中不是这样的
例如,可以使用智能指针,它将在其析构函数中执行delete[]
(或reset()
函数)。如果在调用new[]
后引发异常,这一点尤其有用:
boost::scoped_array<TCHAR> buffer(new TCHAR[length + 1]);
GetWindowText(hwnd, buffer.get(), length + 1);
Str text(buffer.get()); // buffer will be deleted at end of scope.
boost::作用域数组缓冲区(新的TCHAR[length+1]);
GetWindowText(hwnd,buffer.get(),长度+1);
Str text(buffer.get());//将在作用域末尾删除缓冲区。
您的数组分配了new[]
,因此必须使用delete[]
(而不是delete
)删除
您的显式动态分配也是不必要的:
Str text(length+1, 0);
GetWindowText(hwnd, &text[0], length + 1);
text.resize(length); // remove NUL terminator
return text;
在C++03中需要一些理由,不管string
和wstring
是否实际分配了适合作为缓冲区传递的连续内存。C++03标准不保证这一点,但在MSVC++中事实上是这样。如果您不想依赖这一事实,那么向量就有保证,因此您可以将其用于缓冲区:
std::vector<TCHAR> buffer(length+1);
GetWindowText(hwnd, &buffer[0], length + 1);
return Str(buffer.begin(), buffer.end() - 1);
std::向量缓冲区(长度+1);
GetWindowText(hwnd和缓冲区[0],长度+1);
返回Str(buffer.begin(),buffer.end()-1);
直接使用new[]<代码> >向量> <代码>或<代码>字符串< /COD>缓冲区是一个自动变量,所以我不必做任何特殊的事情来确保它的范围结束时被正确地销毁。如果你使用java/C++,那么就不需要任何类型的代码>删除< /代码>。基本类型和类没有什么不同。如果你新建它,它就在堆上,如果你不新建,它就在堆栈上(通常)。但是类可能有内部结构,所以类本身可能在堆栈上,但它使用的一些内部内存可能在堆上。“还请阅读基本类型,如int、char和bool,是在堆栈上创建的”-要么你被骗了,要么你误解了你读到的内容。自动变量在堆栈上创建(这不是保证,这是一个实现细节),并在超出范围时销毁(这是保证的)。通常,不需要动态分配基元类型的对象,您可以为这些类型使用自动变量。但无论如何,您分配的对象没有基元类型,它是一个数组。TCHAR
,它是基元类型。此外,std::string
不是基元type@Evgeni是的,但是de>和TCHAR
是。这是分配的。+1用于深入解释和智能指针用法示例。既然我使用new TCHAR[length+1]
,你是说我需要使用delete[]
?@BrandonMiller,是的。如果new[]
那么delete[]
+1用于std::vector use。提供与作用域数组相同的功能,无需附加依赖项。+1用于向量和字符串用法示例。以及向量连续内存的说明。若要添加到规则中,任何使用placement new构建的
都必须在代码中显式调用其析构函数,如果它是它是一个析构函数。Placement new
允许您在现有内存块中构造某些内容,而不是分配新内存块,如new
和new[]
do。