重复释放是指两次释放同一块内存。下面是一个简单的例子:
int *pi = (int*) malloc(sizeof(int));
*pi = 5;
free(pi);
...
free(pi);
调用第二个free
函数会导致运行时异常。另一个例子不那么明显,涉及指向同一块内存的两个指针。如下所示,如果我们试图第二次释放同一块内存会发生同样的运行时异常。
int *p1 = (int*) malloc(sizeof(int));
int *p2 = p1;
free(p1);
...
free(p2);
内存分配如图2-10所示。
图2-10:重复释放
注意 两个指针引用同一个地址称为别名,这个概念将在别名和强别名讨论。
不幸的是,堆管理器很难判断一个块是否已经被释放,因此它们不会试图去检测是否两次释放了同一块内存。这通常会导致堆损坏和程序终止,即使程序没有终止,它意味着程序逻辑可能存在问题,同一块内存没有理由释放两次。
有人建议free
函数应该在返回时将NULL
或其他某个特殊值赋给自身的参数。但指针是传值的,因此free
函数无法显式地给它赋值NULL
,传递指针的指针会详细讨论这个问题。
评论前必须登录!
注册