new与malloc的区别


new分配内存按照数据类型进行分配,malloc分配内存按照大小分配; new不仅分配一段内存,而且会调用构造函数,但是malloc则不会。new的实现原理?但是还需要注意的是,之前看到过一个题说int p = new int与int p = new int()的区别,因为int属于C++内置对象,不会默认初始化,必须显示调用默认构造函数,但是对于自定义对象都会默认调用构造函数初始化。翻阅资料后,在C++11中两者没有区别了,自己测试的结构也都是为0; new返回的是指定对象的指针,而malloc返回的是void*,因此malloc的返回值一般都需要进行类型转化; new是一个操作符可以重载,malloc是一个库函数; new分配的内存要用delete销毁,malloc要用free来销毁;delete销毁的时候会调用对象的析构函数,而free则不会; malloc分配的内存不够的时候,可以用realloc扩容。扩容的原理?new没用这样操作;
realloc是从堆上分配内存的.当扩大一块内存空间时,realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平;如果数据后面的字节不够,那么就使用堆上第一个有足够大小的自由块,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上.这句话传递的一个重要的信息就是数据可能被移动.
  1. int len =7;  
  2. int * a = (int *) malloc (sizeof(int) * len);  
  3. len++;  
  4. int * aold = a;            //重新分配前保存a的地址  这个是多余的  
  5. a = (int *)realloc(sizeof(int)* len);   //重新分配28+4 = 32字节内存给数组a  
    前面两句定义了1个长度为7的int 类型数组, 每个元素的字节长度是4, 所以共占28byte 内存.
    第3句长度变量+1
    第4句 分两种情况:
       1) 假如数组a 内存里接着的4个字节还没被其他对象或程序占用, 那么就直接把后面4个字节加给数组a, 数组前面7个旧的元素的值不变,  数组a的头部地址也不变.

       2) 假如数组 a内存里接着的4个字节已经被占用了, 那么realloc 函数会在内存其他地方找1个连续的32byte 内存空间, 并且把数组a的7个旧元素的值搬过去,  所以数组a的7个旧元素的值也不变, 但是数组a的头部地址变化了.  但是这时我們无需手动把旧的内存空间释放. 因为realloc 函数改变地址后会自动释放旧的内存, 再手动释放程序就会出错了
new如果分配失败了会抛出bad_alloc的异常,而malloc失败了会返回NULL。因此对于new,正确的姿势是采用try...catch语法,而malloc则应该判断指针的返回值。为了兼容很多c程序员的习惯,C++也可以采用new(nothrow) 的方法禁止抛出异常而返回NULL:

[cpp]  view plain  copy
  1. #include <new>//必须使用new头文件  
  2. Manager * pManager = new (nothrow) Manager();  
  3. if(NULL == pManager)  
  4. {  
  5.     //记录日志  
  6.     return false;  
  7. }  
[cpp]  view plain  copy
  1. void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)  
  2.         {       // try to allocate size bytes  
  3.         void *p;  
  4.         while ((p = malloc(size)) == 0)  
  5.                 if (_callnewh(size) == 0)  
  6.                 {       // report no memory  
  7.                         _THROW_NCEE(_XSTD bad_alloc, );  
  8.                 }  
  9.   
  10.         return (p);  
  11.         }  
调用malloc失败后会调用_callnewh。如果_callnewh返回0则抛出bac_alloc异常,返回非零则继续分配内存。 _callnewh是 一个new handler,通俗来讲就是new失败的时候调用的回调函数。可以通过_set_new_handler来设置。

new和new[]的区别,new[]一次分配所有内存,多次调用构造函数,分别搭配使用delete和delete[],同理,delete[]多次调用析构函数,销毁数组中的每个对象。而malloc则只能sizeof(int) * n;如果不够可以继续谈new和malloc的实现,空闲链表,分配方法(首次适配原则,最佳适配原则,最差适配原则,快速适配原则)。delete和free的实现原理,free为什么知道销毁多大的空间?

猜你喜欢

转载自blog.csdn.net/qq_22238021/article/details/80276362