试图查看释放内存的正确方法,但我找不到确切的答案。我确定它在那里,但是我似乎找不到它,我有点困惑。
这就是我在做什么。我从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 []是否会照顾好它?
答案 0 :(得分:5)
如果可以帮助,请不要使用new
。在现代C ++中,大多数情况下不需要new
。
您可以使用std::vector
,std::array
,std::string
(也许是std::basic_string<TCHAR>
,std::unique_ptr
或std::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 ++)