使用“ new”时是否需要释放分配的wchar内存,或者delete []也会释放它吗?

时间:2019-07-03 10:51:20

标签: c++ arrays struct delete-operator

试图查看释放内存的正确方法,但我找不到确切的答案。我确定它在那里,但是我似乎找不到它,我有点困惑。

这就是我在做什么。我从sUsers创建了一个新的sStructUsers,然后为用户名分配了内存

    struct sStructUsers 
        {
        TCHAR *sName;
        };

    sStructUsers *sUsers = new sStructUsers[TOTALUSERS]();

    // Allocate memory for the TCHARs in sStruct
    for (INT k = 0; k < TOTALUSERS; k++)
        {
        sUsers [k].sName =  (TCHAR*)calloc(128,sizeof(TCHAR))
        }

下一步,我需要对sName成员进行任何工作

    // do work here

现在,要执行清理操作,

    delete[] sUsers;

还是我这样做?

    for (INT k = 0; k < TOTALUSERS; k++)
        {
        free(sUsers[k].sName);
        }
    delete[] sUsers?

我不确定是否需要释放内存或delete []是否会照顾好它?

3 个答案:

答案 0 :(得分:5)

如果可以帮助,请不要使用new。在现代C ++中,大多数情况下不需要new。 您可以使用std::vectorstd::arraystd::string(也许是std::basic_string<TCHAR>std::unique_ptrstd::shared_ptr

如果您确实需要使用new,请制作一个特殊的类来处理。即例如,在构造函数中使用new,在析构函数中使用delete

当然,正如评论中所述,切勿将new / delete与malloc / free混为一谈。完全不需要在C ++中使用这些函数,因为这是C的残余。

编辑:添加了示例,类本身如何处理。

struct sStructUsers 
{
    const int MAX_NAME_SIZE = 128;
    sStructUsers()
    {
        sName = new TCHAR[MAX_NAME_SIZE];
    }
    ~sStructUsers()
    {
        delete sName;
    }
    TCHAR *sName;
};

然后,使用此类时无需任何初始化/清除。

请注意,通常您甚至都不需要这样做,您可以按以下方式定义类:

struct sStructUsers 
{
    std::basic_string<TCHAR> sName;
};

并免费提供完整的string功能。或像这样,如果您确实需要一个指针:

struct sStructUsers 
{
    const int MAX_NAME_SIZE = 128;
    sStructUsers() : sName(new TCHAR[MAX_NAME_SIZE]) {}
    std::unique_ptr<TCHAR[]> sName;
};

或者,正如我前面提到的,请使用其他标准容器。

答案 1 :(得分:1)

应分配每个分配。通过一些代码。正如sklott所写,有一些工具(容器和其他类)可以为您完成工作。如果某些其他代码没有执行此操作,则您的代码应进行释放。

简而言之,您应该同时呼叫free(sUsers[k].sName)delete[] sUsers。就目前而言,delete [] sStructUsers不会释放其中的指针。

(我还可以修改sStructUsers,以便其析构函数直接或通过智能指针进行释放。)

(对于张贴“永远不要将新的/删除的内容与malloc / free混用”的回答者和评论者,请用解释原因的评论来抨击我。了解建议和最佳做法背后的理性总是很重要的。更新:显然,您不能混用new + free或malloc + delete等;这些函数必须正确配对,以免出现堆损坏和泄漏。更好的问题是为什么不对某些分配使用new + delete malloc / calloc + free给其他人[还可以:CoTaskMemAlloc(),HeapAlloc(),VirtualAlloc()或其他平台函数...]。)

答案 2 :(得分:1)

建议使用更好的容器,更惯用的C ++和更现代的做法的评论和答案都很好。

但是您的第二个选择回答了您的紧迫问题

for (INT k = 0; k < TOTALUSERS; k++)
    {
    free(sUsers[k].sName);
    }
delete[] sUsers;

那不会泄漏内存。但是,第一个选择将泄漏,因为仅delete[]个数组不会释放其元素的堆内存。

简而言之,对每个delete[]使用new[],对每个free使用calloc

(只有这样,才可能重构为比C和C ++更接近C ++)