[16] 自由存储(Freestore)管理(上)
(Part of C++ FAQ Lite, Copyright ? 1991-2001, Marshall Cline, cline@parashift.com)
简体中文版翻译:申旻,nicrosoft@sunistudio.com(东日制作室,东日文档)
FAQs in section [16]:
- [16.1] delete p 删除指针 p,还是删除指针所指向的数据 *p?
- [16.2] 可以 free() 一个由 new 分配的指针吗?可以 delete 一个由 malloc() 分配的指针吗?
- [16.3] 为什么要用 new 取代原来的值得信赖的 malloc()?
- [16.4] 可以在一个由 new 分配的指针上使用 realloc() 吗?
- [16.5] 需要在 p = new Fred()之后检查NULL 吗?
- [16.6] 我如何确信我的(古老的)编译器会自动检查 new 是否返回NULL?
- [16.7] 在delete p之前需要检查 NULL吗?
- [16.8] delete p 执行了哪两个步骤?
- [16.9] 在 p = new Fred()中,如果Fred构造函数抛出异常,是否会内存“泄漏”?
- [16.10] 如何分配/释放一个对象的数组?
- [16.11] 如果 delete 一个由new T[n]分配的数组,漏了 [] 会如何?
- [16.12] 当delete一个内建类型(char, int, 等) 的数组时,能去掉 [] 吗?
- [16.13] p = new Fred[n]之后,编译器在delete[] p的时候如何知道有 n 个对象被析构?
- [16.14] 成员函数调用delete this合法吗?
- [16.15] 如何用 new 分配多维数组?
- [16.16] 但前一个 FAQ 的代码太技巧而容易出错,有更简单的方法吗?
- [16.17] 但上面的 Matrix 类是针对 Fred的!有办法使它通用吗?
- [16.18] 还有其他方法建立 Matrix 模板吗?
[16.1] delete p 删除指针 p,还是删除指针所指向的数据 *p?
指针指向的数据。
关键字应该是 delete_the_thing_pointed_to_by。同样的情况也发生在 C中释放指针所指的内存: free(p)实际上是指free_the_stuff_pointed_to_by(p)。
[ Top | Bottom | Previous section | Next section ]
[16.2] 可以 free() 一个由 new 分配的指针吗?可以 delete 一个由 malloc() 分配的指针吗?
不!
在一个程序中同时使用 malloc() 和 delete 或者同时使用 new 和 free() 是合情合理合法的。但是,对由 new 分配的指针调用 free(),或对由 malloc() 分配的指针调用 delete,是无理的、非法的、卑劣的。
当心!我偶尔收到一些人的e-mail,他们告诉我在他们的机器 X 上和编译器 Y 上工作正常。但这并不能使得它成为正确的!有时他们说:“但我只是用一下字符数组而已”。即便虽然如此,也不要在同一个指针上混合malloc() 和 delete,或在同一个指针上混合new 和 free()。如果通过p = new char[n]分配,则必须使用delete[] p;不可以使用free(p)。如果通过分配p = malloc(n),则必须使用free(p);不可以使用delete[] p 或 delete p!将它们混合,如果将代码放到新的机器上,新的编译器上,或只是同样编译器的新版本上,都可能导致运行时灾难性的失败。
记住这个警告。
[ Top | Bottom | Previous section | Next section ]
[16.3] 为什么要用 new 取代原来的值得信赖的 malloc()?
构造函数/析构函数,类型安全,可覆盖性(Overridability)。
- 构造函数/析构函数:与 malloc(sizeof(Fred))不一样,new Fred() 调用 Fred 的构造函数。同样,delete p 调用 *p 的析构函数。
- 类型安全:malloc() 返回一个没有类型安全的 void* 。new Fred() 返回一个正确类型(一个 Fred*)的指针。
- 可覆盖性:new 是一个可被类重写/覆盖的算符(operator),而 malloc() 在类上没有可覆盖性。
[ Top | Bottom | Previous section | Next section ]
[16.4] 可以在一个由 new 分配的指针上使用 realloc() 吗?
不可!
realloc() 拷贝时,使用的是位拷贝(bitwise copy )算符,这会打碎许多 C++ 对象。C++对象应该被允许拷贝它们自己。它们使用自己的拷贝构造函数或者赋值算符。
除此之外,new 使用的堆可能和 malloc() 和 realloc() 使用的堆不同!
[ Top | Bottom | Previous section | Next section ]