关于new的定位表达式的疑问.

021850524 2006-03-04 11:13:35
关于new的定位表达式的疑问.
如果申请了一块char*内存, 用char *p指向它, char *p = new char[SIZE];
然后用new的定位表达式将对象全部在p中生成, char *pT = new (p) T[SIZE/20];
那么new出来的对象怎么析构?
用单独先delete掉对象, 然后再delete掉这块p指向的char*的内存吗?
我看C++Primer中写的, 是不用delete掉对象, 直接delete掉char*的内存.
但是如果对象中包含指针数据成员, 可能关联到别的内存区, 也可能关联到系统资源,
那么它们是怎么被析构的?

我写了一段代码, 发现并没有调用析构函数:
//另外, 发现在BCC下没有编译通过, 提示new表达式出错, 提示:Could not find a match for 'operator new[](unsigned int, char *)'
//在GCC(版本3.2.3)下, 也没有通过, 需把int i = sizeof T;这句改成int i = sizeof(T);不清楚为什么.
//VC和VS2003下, 顺利通过.

#include <iostream>
#include <new>

using namespace std;

class T {
public:
T() {
cout<<"T"<<endl;
}
~T() {
cout<<"~T"<<endl;
}
};

int main()
{
int i = sizeof T;
char *p = new char[i * 1000];
T *pT = new (p) T[20];
delete []p;

return 0;
}
...全文
104 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
ox_thedarkness 2006-03-05
  • 打赏
  • 举报
回复
ISO C/C++规定sizeof 这样使用:
当a是对象时,用 sizeof a 或 sizeof (a)
当a是类型时,只能用 sizeof (a)

BCC没用过,如果不支持replacement new 大概是太老了


更标准的做法是,用全局版 operator new 申请 raw (生鲜)内存。
注意手动析构时,应该模仿C++默认行为,以和构造相反的顺序调用析构函数。虽然大部分不至于出错,但是养成这个习惯可以避免未来潜在的麻烦。

class T {
int i;
public:
T() {
static int n;
i = n++;
cout<<"T() #"<<i<<endl;
}
~T() { cout<<"~T() #"<<i<<endl;}
};

int main(){
void *p = operator new( sizeof T() * 1000);

T *pT = new (p) T[20];
for( int i = 20-1; i>= 0; --i )
pT[i].~T();

delete p;
}
ox_thedarkness 2006-03-05
  • 打赏
  • 举报
回复
1 replacement new 不能delete。
2 应该手动调用其析构函数。


参考 Thinking in C++第一版 12.5.5 或者 More Effective C++ 条款8,第39~41面

64,685

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧