报错原因:
-
- 应该被释放的指针无效(或者不在有效)
-
- 程序运行期间,heap在某个时刻被损坏
几下几种场景
- A. 指针一开始并不指向堆中的内存
char *mem = "not on the heap!";
free(mem);
- B. 指针的值不是malloc/calloc返回的原始地址
unsigned char *mem = (unsigned char*)malloc(100);
mem++;
free(mem); // mem has wrong address!
由于 mem 的值在递增后不再是 64 字节对齐,因此健全性检查可以轻松看出它不可能是堆指针!
- C. 不匹配的new[ ] 和 delete
struct A {
int a = 0;
~A() {// destructor is not trivial!
std::cout << a << "\n";
}
};
A *mem = new A[10];
delete mem;
当new 数组对象时,前4个字节保存的是此对象数组中对象的个数。
new[]/delete[] 与 new/delete的区别
- D. 重复释放
unsigned char *mem = (unsigned char*)malloc(10);
free(mem);
free(mem); # the pointer is already freed
struct A {// bad: doesn't adhere to rule of three
int* ptr;
A(int i): ptr(new int(i))
{
}
~A()
{
delete ptr;
}
};
{
A a(0);
A b = a; // a and b share pointer: a.ptr == b.ptr
} // here destructors of b and a called => problem
// at first b.ptr gets deleted
// deleting (already deleted) a.ptr leads now to UB/error.
- E. 来自另一个运行时/内存管理器的指针
Windows 程序能够一次运行多个程序:每个使用的 dll 都可能有自己的运行时/内存管理器/堆,因为它是静态链接的或者因为它们具有不同的版本。因此,在一个 dll 中分配的内存在另一个使用不同堆的 dll 中释放时可能会失败