我编写了一个zap()函数来解除分配1-d数组,如下所示。
void zap(double *(&data))
{
if (data != NULL)
{
delete [] data;
data = NULL;
}
return;
}
我的印象是if data != NULL
不会尝试释放从未分配过的内存,但我认为我错了。我遇到了以下实施问题。
void fun()
{
int condition = 0;
double *xvec;
double *yvec;
allocate_memory_using_new(yvec); //a function that allocates memory
if (condition == 1) allocate_memory_using_new(xvec);
//some code
//deallocate memory:
zap (yvec);
zap (xvec); //doesn't work
return;
}
输出如下:
Unhandled exception at 0x6b9e57aa (msvcr100d.dll) in IRASC.exe: 0xC0000005: Access
violation reading location 0xccccccc0.
所以我意识到,当很明显指针从未真正使用过时,尝试调用zap并不是理想的事情。我只是想知道是否有办法在zap()函数的某个点检查指针的地址以避免异常。提前感谢您的帮助和见解!
答案 0 :(得分:7)
指针不会被神奇地初始化为0,只有当它们是全局或静态时。 您需要这样做:
double *xvec = NULL;
double *yvec = NULL;
如果不这样做,它们会包含留在堆栈中的随机垃圾。这个垃圾大部分时间都是不 NULL
。
另外,您无需核对NULL
,因为delete
在这种情况下是无操作:
double* xvec = NULL;
delete xvec; // perfectly valid
此外,如果您使用的是Visual Studio 2010,我建议您使用nullptr
代替NULL
。
答案 1 :(得分:0)
xvec和yvec的值指向随机数,而不是NULL。我认为您的allocate_memory函数无法正常工作,因为它通常会返回指向内存块的指针,您将分配给xvec和yvec
答案 2 :(得分:0)
在C ++中,指针没有像其他语言那样自动初始化为NULL(想想Java),因此xvec
(指针)的值是未定义的,并且在测试时可能是或不是NULL。
void fun()
{
double *xvec; // value of xvec undefined, might be 0 or not
// ...
zap (xvec); // if it is not 0, you will try to delete: Undefined Behavior
}
简单的解决方案是在定义double *xvec = 0;
中初始化指针。此外,您不需要在0
函数中测试NULL(或zap
),delete
如果在空指针上调用则不会导致未定义的行为:
template <typename T>
inline void zap( T *& p ) {
delete p;
p = 0;
}
答案 3 :(得分:0)
我已经得出结论new
和delete
的数组形式有资格作为C ++反模式 - 它们看似合理,但实际上几乎任何和所有使用它们基本上都能保证领先比可用的代码更悲伤和更多的问题。
因此,我会说尝试修复你的zap
有点像找到一个刚刚遭遇火灾并且至少得到3次 rd 度烧伤的女性85%的身体,并试图通过修剪她从火上逃脱时断裂的指甲使她变得更好。