人工低能

Artificial Imbecility(AI) may bedefined as the branch of IQ hat is concerned with the automation of imbecility behavior

原创 混沌 IN C++::动态资源管理陷阱收藏

新一篇: 混沌 IN C++::模板参数的奥秘 | 旧一篇: 混沌 In C++::是类型?还是函数调用?

难度:

先阅读下面的代码然后来解答下面的那个问题

 

struct A

{};

 

int main()

{

A *p = new A;

p->~A();

free(p);

}

 

问题:new/delete malloc/free 有哪些区别?

 

 

 

答:new/delete 会在分配的内存上调用对象的构造函数和析构函数来初始化和销毁对象,而 malloc/free 却不能。更重要的是new/delete malloc/free 不能混用。

new 是在自由存储区中分配内存,delete 是负责释放自由存储区中的内存

malloc 是在堆中分配内存,free 则负责释放。

自由存储区和堆的访问方式是不同的,或者说是与平台相关的,如果混用那么必将导致程序崩溃。在某些编译器上也许不会出现问题,但永远相信这是错误的、不可移植的。

 

现在,上面那段代码有问题吗?

发表于 @ 2004年06月29日 05:25:00|评论(loading...)|编辑|收藏

新一篇: 混沌 IN C++::模板参数的奥秘 | 旧一篇: 混沌 In C++::是类型?还是函数调用?

评论

#young 发表于2004-06-29 21:47:00  IP: 221.232.122.*
这个程序如果编译器不够聪明的话,一定会出问题!
#辣子鸡丁 发表于2004-06-29 13:28:00  IP: 222.183.140.*
to duyanning
这是概念的划分问题

to 爱上小白
错误是必然的。这中代码是不可移植的
#C++新手 发表于2004-06-29 14:06:00  IP: 218.80.223.*
我觉得有问题
p->~A();
free(p);

里面P被释放了两次,会导致不可预期的错误。
#bluecoff 发表于2004-06-30 09:24:00  IP: 221.232.93.*
当然不对,new()的本质是用operator new()然后类的construct而成,所以对应的应该用delete()的~Classname()和 operator delete()来解,除非operator new()被重裁如
void* operator new()
{
return malloc();
}
上面代码有可能(只是有可能,因为分配的内存不一定符合construct的要求)通过。
#bluecoff 发表于2004-06-30 09:28:00  IP: 221.232.93.*
更正一下,少两个形参
void* operator new(size_T size)
{
return malloc(size);
}






在我的Dev里面编译, 没有发生错误

那是因为Dev中的operator new()的原形就是
void* operator new(size_T size)
{
return malloc(size);
}



#Dreamer7901 发表于2004-06-30 09:50:00  IP: 221.239.81.*
To jink: 在实现对象池的时候,~加free和placement new配合是很有用的。
#爱上小白 发表于2004-06-29 11:18:00  IP: 218.242.221.*
在我的Dev里面编译, 没有发生错误.
#dockbar 发表于2004-06-29 11:42:00  IP: 218.80.81.*
就像吃饭吃到苍蝇有没有问题? 呵呵
#duyanning 发表于2004-06-29 11:56:00  IP: 222.90.12.*
我有疑问:你说的自由存储区是指什么?包括堆?或者是自己静态分配的空间?对吗?
#Caoyu015 发表于2004-06-30 11:41:00  IP: 218.14.30.*
如果是free释放的是堆上的空间的话,那么对于在自由存储区分配内存并且调用对象constructor的new来说这样的释放不一定正确,起码是不可移植的。
#ahao 发表于2004-06-29 19:13:00  IP: 221.137.216.*
这取决于编译器实现
#seacloud 发表于2004-06-29 20:03:00  IP: 61.170.213.*
To C++新手:
调用~A()并没有释放A对象。
#别逗了 发表于2004-07-01 17:49:00  IP: 61.129.126.*
搞虾米也不知道,标准叫你new了之后一定用delete释放,你偏偏来个~加free,你想干嘛?这么有个性,有能耐别调人家的函数自己一行行码delete.
-----------------------------------------
建议看看STL容器中关于内存分配的部分,看看有多少是没有直接new/delete的。在写这样的代码时,如果再混进点memory pool之类的东西,写错代码的情况一点也不稀奇。
#freezingfire 发表于2004-07-01 13:05:00  IP: 221.216.152.*
"将用new申请的内存,用free释放,或将用malloc申请的内存,用delete释放,其结果未有定义"

- 《Effective C++》

未有定义就是说C++标准里没说会怎么样,这有什么好讨论的?

那个自由存储区是什么东东?第一次听说,作者不会是故意卖关子吧。虚荣!
#run_mei 发表于2004-07-02 18:09:00  IP: 218.80.155.*
同意 bluecoff 上面的代码是否能通过,如果你重载的话,取决于你如何重载,同时取决于编译器。
#dnnupt 发表于2004-07-01 15:30:00  IP: 218.12.100.*
to duyanning

我这段时间在看MCD,里面的小对象分配一部分也频繁出现“自由存储区”原文为“free store”,我推测为就是指利用new在heap分配的DD,不知道我的推测是否正确

其实刚刚在读这篇文章的时候觉的“鸡丁”真的有点“哗众取宠”之嫌,但是我细细想来这个问题真的挺有意思。
p->~A();
free(p);
上面这两句完成的其实就是delete的任务,可是确错误的 :(,虽然我还是认为它很像是正确的!:)

那------->(malloc+placement new)+delete应该也和文章中的错误一样吧
#mayax 发表于2004-07-09 20:54:00  IP: 219.136.141.*

看这样的代码:

class A{
int a;
};


static A * p = NULL;
static char place[sizeof(A)];

static void init_A( void )
{
p = new ( place ) A();
}

static void release_A( void )
{
p->~A();
}

——————————————

有时候 placement new + ~ 能尽量避免直接使用缺省堆,对于某些地方的性能优化是非常有效的。
发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © Jinhao