读书人

new跟malloc区别

发布时间: 2013-11-29 13:49:33 作者: rapoo

new和malloc区别
new/delet和malloc/free底层如何实现的?free两次系统会报错,系统是如何感知到free两次的
[解决办法]
两者的区别 google下很多的很全的!
free释放后,指针指向的内存释放掉了,不是指针本身哦!
如果没有置空的话,指向的已经不再是堆上的内存地址了!再次释放就出错了!
至于底层实现,可以找源码瞧瞧!每次free都是有停止的标志量的!

[解决办法]
建议Google,而不是CSDN。。。
[解决办法]
http://blog.csdn.net/eroswang/article/details/4265024

void free(void *ptr) ...{
struct mem_control_block *free;
free = ptr - sizeof(struct mem_control_block);
free->is_available = 1;
return;
}

做了标记的。
[解决办法]
new封装了malloc,默认情况下,他会自动调用所有相关的构造函数(本身、基类、成员等),还会抛出相应的异常。当然你这些功能全部关掉后就和malloc一样了。malloc仅仅是分配内存而已,成员的初始化,基类的构造函数都不会进行。

底层的操作很难说清楚,我也不太清楚,你可以看源码(估计看了也不懂)。

我找到一段free的源码,你可以看看,比malloc简单多了。全部源码都在这个malloc.c文件里。当然也可能跟具体的实现有关,不同系统不同版本,仅供参考:

void
free(void *ptr) {
malloc_zone_t*zone;
size_tsize;
if (!ptr)
return;
zone = find_registered_zone(ptr, &size);
if (!zone) {
malloc_printf("*** error for object %p: pointer being freed was not allocated\n"
"*** set a breakpoint in malloc_error_break to debug\n", ptr);
malloc_error_break();
if ((malloc_debug_flags & (SCALABLE_MALLOC_ABORT_ON_CORRUPTION
[解决办法]
SCALABLE_MALLOC_ABORT_ON_ERROR)))
abort();
} else if (zone->version >= 6 && zone->free_definite_size)
malloc_zone_free_definite_size(zone, ptr, size);
else
malloc_zone_free(zone, ptr);
}

[解决办法]
引用:
Quote: 引用:

底层,看你要深入到什么程度。

如果我们看语法层次,new是个操作符,malloc只是个函数。

如果讲具体的行为,new还负责调用构造函数,malloc则只是分配内存。

深入到CRT,一般来说,new都是用malloc间接实现的,当然了,有些C++的new的实现还不止malloc的那么多。

要是涉及到内存分配的细节,可以参考STL的Allocator,不是一会儿事儿,但是有参考意义。

想知道细节,看gcc源码什么的吧?我是没看过,我都是Google出来的。

因为遇到很多问题比如上面提到的free两次系统会报错,系统是如何感知到free两次的,还有在哪些情况下
这两个可以相互使用 比如new开辟free释放 malloc开辟delete释放 这些东西搞不懂只能求助了



或许有些CRT库允许你new的可以free,但这肯定不是好的做法,在有些环境中甚至是错误的做法。
逆行不一定出事儿,但是违章。

系统不会感知所谓的两次的,内存被reclaimed后,一般是mark一下而已,当再次free的时候,会check到一些flag,我猜的。

Google "free twice":
第一篇文章是:
http://stackoverflow.com/questions/3117615/why-free-crashes-when-called-twice




[解决办法]
引用:
Quote: 引用:

底层,看你要深入到什么程度。

如果我们看语法层次,new是个操作符,malloc只是个函数。

如果讲具体的行为,new还负责调用构造函数,malloc则只是分配内存。

深入到CRT,一般来说,new都是用malloc间接实现的,当然了,有些C++的new的实现还不止malloc的那么多。

要是涉及到内存分配的细节,可以参考STL的Allocator,不是一会儿事儿,但是有参考意义。

想知道细节,看gcc源码什么的吧?我是没看过,我都是Google出来的。

因为遇到很多问题比如上面提到的free两次系统会报错,系统是如何感知到free两次的,还有在哪些情况下
这两个可以相互使用 比如new开辟free释放 malloc开辟delete释放 这些东西搞不懂只能求助了

上面已经说了free是有标志位的!malloc 的只能用free,new的只能用delete必须配套使用!
不能乱来的! new/delete只是一个操作符,实现通过malloc/free来完成的
[解决办法]
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

底层,看你要深入到什么程度。

如果我们看语法层次,new是个操作符,malloc只是个函数。

如果讲具体的行为,new还负责调用构造函数,malloc则只是分配内存。

深入到CRT,一般来说,new都是用malloc间接实现的,当然了,有些C++的new的实现还不止malloc的那么多。

要是涉及到内存分配的细节,可以参考STL的Allocator,不是一会儿事儿,但是有参考意义。

想知道细节,看gcc源码什么的吧?我是没看过,我都是Google出来的。

因为遇到很多问题比如上面提到的free两次系统会报错,系统是如何感知到free两次的,还有在哪些情况下
这两个可以相互使用 比如new开辟free释放 malloc开辟delete释放 这些东西搞不懂只能求助了

上面已经说了free是有标志位的!malloc 的只能用free,new的只能用delete必须配套使用!
不能乱来的! new/delete只是一个操作符,实现通过malloc/free来完成的


为何必须配套使用呢?

对于pod类型的确无需配套,可以malloc、delete或者new、free,但是应该保持一致,方便阅读、维护。虽然new、delete封装了malloc、free,但new、delete还会处理很多事(除非你选择关闭这些功能)。而且在C++中,很多struct、class都不是pod类型的,单单用malloc、free是不行的,需要用new、delete。因此直接用new、delete会更好些。
[解决办法]
前一个问题,可以认为new = malloc + 调用构造函数
后一个问题,随便找吧操作系统的书看看内存管理部分就知道了
malloc出来的内存,会通过一个首地址指针链表进行管理,free的时候会查找这个链表,将找到的指针(及记录的内存长度)释放到空闲内存链表。free第2次,在链表中找不到这个地址,就会报错。
[解决办法]
为何“套用”很好解释。
你理解了,就知道为什么有时候malloc的,也是没法free的。

malloc是从(某)一片内存上,划分出来一块给你用,free是把这块内存还回去。
像这样的某一片内存,一个进程内可能不止一个。。。

你不能从A片内存取出来一小块内存,还给B片内存。

某个程序,有多个模块,有的模块链接了A种CRT,那么就从A片内存malloc 内存。也有模块从链接了B类CRT,那么就从B片内存malloc。那么这个malloc到的内存,你不能free给A。【这就解释了我第二行说的】
-----------------------
你可能不清楚什么叫free给A,什么叫free给B(因为free就一个参数啊,没有哪个参数指定了Module这个东东),这是看调用位置的,简单说,你free() function 代码出现在A模块,那么就是吧某块内存free给A片内存了。

以上说的,其实就是你可能听到过的“谁创建,谁释放”。
-----------------------
怎么做到谁创建,谁释放?
一个程序是多个模块构成的,内存从这个模块创建出来,到处传递,最后怎么做到还是由创建的模块来释放呢?
C的做法我不是太清楚。。。

C++的某种做法我还是知道的。其实这也是某种C代码的处理方法。

比如说 class Image;

在模块A中new出来,那么我们就知道是A模块链接的CRT的堆提供的内存。
然后Image的instance pointer pImage被传递到了B模块。

这时候,逻辑决定delete pImage; 如果B模块有自己的堆。那么这个delete可能就会失败。

C++的一种practice,为了防止这种情况。可以在Image类中,提供一个static的CreateInstance方法,和成员的Release方法。
COM组件大概是这么做的。

-----------------
C语言类似的,一个模块,如果这个模块暴露了函数ModuleA_CreateXObject,ModuleA_CreateYObject...,给其他的模块用,那么你应该再暴露出来ModuleA_Free方法,这样ModuleA_Create***Object和ModuleA_Free就对应上了。

再回顾一下,是不是看到了谁创建,谁释放的形式了?
------------------------------------------
学个C++真TMD烦,没听说Java,Python,Ruby要考虑这种情况,写点代码要了命了。
其实就我知道的一点VC++小知识,现在多个模块一般都是链接到同一个CRT上面,(我以前学习用VC6的时候,倒是总遇到这类事情,这几年好像不用考虑了),工具升级了~~也就是多个模块共享同一个堆,这样你就new/delete,
malloc/free吧,比Java麻烦不了哪去了。

但是也别new的去free,malloc的delete,这是作死的节奏。!!



[解决办法]
new跟malloc区别
[解决办法]
引用:
Quote: 引用:

Quote: 引用:

前一个问题,可以认为new = malloc + 调用构造函数
后一个问题,随便找吧操作系统的书看看内存管理部分就知道了
malloc出来的内存,会通过一个首地址指针链表进行管理,free的时候会查找这个链表,将找到的指针(及记录的内存长度)释放到空闲内存链表。free第2次,在链表中找不到这个地址,就会报错。

应该是默认情况下 new = malloc + 调用构造函数 + 抛出异常 吧!
我们老师也说new实际还是调用了malloc


new只是一个外壳,里面具体用什么分配器可以通过重载new操作符实现替换的。当然默认是通过malloc,这仅仅是为了保证兼容于Crt的内存分配方式。
[解决办法]
既然说new。。。到底是new操作(new operator,即类似new int、new A等)还是new操作符(void * operator new(size_t cb))?new操作底层先调用new操作符分配内存,成功返回的话然后再调用类型的构造函数,否则视情况返回空指针或抛出异常。
我觉得按楼主的意思问的应该只是new操作符部分,而不涉及到new操作。如果是这样的话new操作符仅仅涉及到内存分配的细节,而不涉及到类型相关的任何部分,比如构造函数什么的。
[解决办法]
new必须与delete配套, malloc与free没有强制规定。
new 出来的东西如果用 free 释放,一是析构函数没有被调用, 二是 new 是可以重载的,也就是说它不一定用 malloc 来分配内存, free 函数表示很迷惑(当然未重载的delete也很迷惑,但至少你可以重载)。

free 两次报错这个事依赖于实现,如果运行时没有报错也不能算运行时实现有问题。 毕竟标志检查也只能是个概率问题,谁能保证那块内存在两次delete之间没有正好被别的代码抢到呢?

读书人网 >C++

热点推荐