0

当谈到 C++ 中的内存管理时,我是个新手。我读到如果你用new关键字创建一个类,你必须delete让对象释放它的内存。我还读到原始类型(例如int和)是在堆栈上创建的charbool这意味着它们在超出范围时会被删除。

但是用new关键字创建的原始类型呢?我需要明确调用delete吗?这些是像类一样在堆上创建的吗?或者由于它们是原始的,它们仍然在堆栈上创建吗?

我问是因为我正在LPTSTR使用 new 关键字分配 a,但我担心如果我不调用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("");
    }
}

我需要打电话delete吗?不久前,我尝试使用GlobalAlloc()and GlobalFree(),但是在运行时我收到一条错误消息,说明有关非法修改堆栈的信息,我没有确切的错误消息,因为这是不久前的情况。此外,除了您的回答之外,如果您想给我一些您认为有助于了解更多有关 C++ 内存管理的资源,那就太好了。

4

5 回答 5

8

对于每一个都new必须有一个delete,对于每一个都new[]必须有一个delete[]。请注意,分配的内存new[]必须使用 删除delete[],而发布的代码中并非如此。

boost::scoped_array例如,可以使用智能指针,它将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.
于 2012-10-26T10:28:58.237 回答
7

您的数组已分配,new[]因此必须使用delete[]( not delete ) 删除。

您也不需要显式动态分配:

Str text(length+1, 0);
GetWindowText(hwnd, &text[0], length + 1);
text.resize(length); // remove NUL terminator
return text;

在 C++03 中需要一些理由,是否stringwstring实际分配连续内存,适合作为缓冲区传递。C++03 标准不保证这一点,但在 MSVC++ 中确实如此。如果您不想依赖这个事实,那么可以保证矢量,因此您可以将其用于缓冲区:

std::vector<TCHAR> buffer(length+1);
GetWindowText(hwnd, &buffer[0], length + 1);
return Str(buffer.begin(), buffer.end() - 1);

new[]在 C++中直接使用是非常罕见的。在这两种情况下,我的vectorstring缓冲区都是一个自动变量,所以我不需要做任何特别的事情来确保它在其作用域结束时被正确地销毁。

于 2012-10-26T10:42:49.173 回答
2

是(除非您使用智能指针或类似方法为您删除它)

于 2012-10-26T10:28:00.937 回答
2

是的,规则很简单。你分配的所有东西都new需要被释放delete;并且所有分配的东西都new[]需要被释放delete[]

为了减少出错的机会,最好使用容器、智能指针或其他RAII样式的对象来管理动态资源,而不是记住delete自己使用。

于 2012-10-26T10:28:21.263 回答
0

当然,无论分配什么类型。它仍然有内存空间。

于 2012-10-26T10:28:10.283 回答