moa*_*ala 17 c++ macros pointers memory-management
有没有什么好的理由(除了"宏是邪恶的",也许)不使用以下宏?
#define DELETE( ptr ) \
if (ptr != NULL) \
{ \
delete ptr; \
ptr = NULL; \
}
#define DELETE_TABLE( ptr ) \
if (ptr != NULL) \
{ \
delete[] ptr; \
ptr = NULL; \
}
Run Code Online (Sandbox Code Playgroud)
Goz*_*Goz 42
我个人更喜欢以下
template< class T > void SafeDelete( T*& pVal )
{
delete pVal;
pVal = NULL;
}
template< class T > void SafeDeleteArray( T*& pVal )
{
delete[] pVal;
pVal = NULL;
}
Run Code Online (Sandbox Code Playgroud)
他们最终编译成完全相同的代码.
可能有一些奇怪的方法你可以打破#define系统,但是,个人(这可能会让我呻吟;)我不认为这是一个很大的问题.
CB *_*ley 30
因为它实际上并没有解决很多问题.
实际上,大多数悬空指针访问问题来自这样一个事实:在程序的其他地方存在另一个指向同一对象的指针,后来用于访问已删除的对象.
将未知数量的指针副本中的一个归零可能会有所帮助,但通常这是一个指针即将超出范围,或者设置为指向任何情况下的新对象.
从设计的角度来看,手动调用delete还是delete[]比较少见的.按价值计算,而不是在那里appropriatem使用动态分配的对象使用的对象std::vector,而不是动态分配数组,并包裹有以适当的智能指针动态分配对象的所有权(如auto_ptr,scoped_ptr或shared_ptr)来管理他们的一生都设计方法,使更换delete并且delete[]"更安全"的宏观是一种相对较低的收益方法.
Ara*_*raK 16
因为可以删除NULL(0)指针.无需检查指针是否实际NULL(0)存在.如果要将指针设置为NULL,则在删除之后,可以在delete不使用宏的情况下全局重载运算符.
关于第二点我似乎错了:
如果要将指针设置为NULL,则在删除之后,可以
delete全局重载运算符
问题是,如果你超载全球new和delete,你可以有这样的事情:
void* operator new(size_t size)
{
void* ptr = malloc(size);
if(ptr != 0)
{
return ptr;
}
throw std::bad_alloc("Sorry, the allocation didn't go well!");
}
void operator delete(void* p)
{
free(p);
p = 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,如果你设置p = 0;了重载delete,你实际上是设置local一个,而不是原始p.基本上,我们在重载中获得指针的副本delete.
对不起,这是我的头脑,我现在再考虑一下.无论如何,我会写模板内联函数来做事而不是写EVIL MACROS :)
moa*_*ala 13
因为已经在winnt.h中定义了DELETE:
#define DELETE(0x00010000L)
您的宏失败有几个原因:
DELETE (getPtr());无法编译,因为您无法将函数调用设置为null.或者如果指针是const,您的宏也将失败.delete NULL是标准允许的.最后,正如克里姆纳所说,你正试图解决一个本来就不存在的问题.你为什么要手动调用删除?`你不使用标准库容器吗?智能指针?堆栈分配?RAII?
正如Stroustrup之前所说,避免内存泄漏的唯一方法是避免必须调用delete.