赞
踩
目录
三、总结:malloc/free和new delete的区别
不同的数据,有不同的存储需求,各区域满足不同的需求。数据段也称为静态区,代码段也称为常量区。
栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口 创建共享共享内存,做进程间通信。
堆用于程序运行时动态内存分配,堆是可以上增长的。
数据段--存储全局数据和静态数据。
代码段--可执行的代码/只读常量。
calloc和malloc 区别:malloc + memset =calloc。calloc开空间,且把每个字节都置为0。总的来说,如果你需要分配一块内存,并且希望其中的内容被初始化为零,那么可以使用calloc;如果你只是需要分配一块内存,并不关心其初始值,那么可以使用malloc。
对指针的工作方式有一定了解后,来看看它如何实现在程序运行时分配内存。前面我们都将指针初始存空间分配。化为变量的地址:变量是在编译时分配的有名称的内存,而指针只是为可以通过名称直接访问的内存提供了一个别名。指针真正的用武之地在于,在运行阶段分配未命名的内存以存储值。在这种情况下,只能过指针来访问内存。在C语言中,可以用库函数 malloc()来分配内存:在 C++中仍然可以这样做,但C++还有更好的方法一new运算符。 int *pn = new int
new int告诉程序,需要适合存储int 的内存。new 运算符根据类型来确定需要多少字节的内存。然后,它找到这样的内存,并返回其地址。接下来,将地址赋给 pn,pn 是被声明为指向 int 的指针。现在,pn是地址,而*pn是存储在那里的值。将这种方法与将变量的地址赋给指针进行比较
int higgens;int* t = &higgens;
在这两种情况(pn和pt)下,都是将一个 int 变量的地址赋给了指针。在第二种情况下,可以通过名称higgens来访问该int,在第一种情况下,则只能通过该指针进行访问。这引出了一个问题:pn 指向的内存没有名称,如何称呼它呢?我们说pn 指向一个数据对象,这里的“对象”不是“面向对象编程”中的对象,而是一样“东西”。术语“数据对象”比“变量”更通用,它指的是为数据项分配的内存块。因此,变量也是数据对象,但pn指向的内存不是变量。乍一看,处理数据对象的指针方法可能不太好用,但它使程序在管理内存方面有更大的控制权。
为一个数据对象(可以是结构,也可以是基本类型)获得并指定分配内存的通用格式如下: typeName * pointer_name = new typeName
当需要内存时,可以使用new来请求,这只是 C++内存管理数据包中有魅力的一个方面。另一个方面是delete 运算符,它使得在使用完内存后,能够将其归还给内存池,这是通向最有效地使用内存的管教一步。归还或释放(free)的内存可供程序的其他部分使用。使用 delete 时,后面要加上指向内存块的指针(这些内存块最初是用new分配的)。
int *pn = new int; delete pn;
这将释放pn指向的内存,但不会删除指针 pn本身。例如,可以将 ps 重新指向另一个新分配的内存。一定要配对地使用 new和delete。否则将发生内存泄漏(memory leak),也就是说,被分配的内存再也无法使用了。如果内存泄漏严重,则程序将由于不断寻找更多内存而终止。
警告:只能用delete来释放使用new分配的内存。然而,对空指针使用 delete 是安全的。
如果程序只需要一个值,则可能会声明一个简单变量,因为对于管理一个小型数据对象来说,这样做比使用new和指针更简单,尽管给人留下的印象不那么深刻。通常,对于大型数据(如数组、字符串和结构),应使用 new,这正是new 的用武之地。例如,假设要编写一个程序,它是否需要数组取决于运行时用户提供的信息。如果通过声明来创建数组,则在程序被编译时将为它分配内存空间。不管程序最终是否使用数组,数组都在那里,它占用了内存。在编译时给数组分配内存被称为静态联编(static binding),意味着数组是在编译时加入到程序中的。但使用new时,如果在运行阶段需要数组,则创建它。如果不需要,则不创建。还可以在程序运行时选择数组的长度。这被称为动态联编 (dynamic binding),意味着数组是在程序运行时创建的。这种数组叫作动态数组 (dynamic array)。使用静态联编时,必须在编写程序时指定数组的长度。使用动态联编时,程序将在运行时确定数组的长度。
在C++中,创建动态数组很容易:只要将数组的元素类型和元素数目告诉 new 即可。必须在类型名后加上方括号,其中包含元素数目。例如,要创建一个包含 10个nt 元素的数组,可以这样做:
int * psome = new int [10];
运算符返回第一个元素的地址。在这个例子中,该地址被赋给指针 psome。当程序使用完new 分配的内存块时,应使用 delete 释放它们。然而,对于使用 new 创建的数组,应使用另一种格式的delete来释放: delete [] psome
方括号告诉程序,应释放整个数组,而不仅仅是指针指向的元素。请注意 delete 和指针之间的方括号。申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用 new[]和delete[],注意:匹配起来使用。C++的早期版本无法识别方括号表示法。然而,对于ANSIISO标准来说,new与delete的格式不匹配导致的后果是不确定的,这意味着程序员不能依赖于某种特定的行为。
总之,使用new和delete 时,应遵守以下规则。
不要使用delete来释放不是new分配的内存。
不要使用delete 释放同一个内存块两次。
如果使用new[]为数组分配内存,则应使用 delete[]来释放。
如果使用new为一个实体分配内存,则应使用 delete(没有方括号)来释放。
对空指针应用 delete 是安全的。
为数组分配内存的通用格式如下: type_name * pointer name = new type_name[num_elements];
运算符new和new[]分别调用如下函数:
void* operator new(std::size_t); void* operator new[](std::size_t);
这些函数被称为分配函数(alloction function),他们位于全局名称空间中。通用也有由delete和delete[]调用的释放函数(deallocation function):
void* operator delete(void *); void operator delete[](void *);
operator new 和operator delete是库里面的全局函数,封装了malloc和free。
new:1、申请对象空间(operator new) 2、调用构造。operator new是为了处理malloc失败时抛异常。 delete:1、调用析构 2、operator delete释放对象。
new T[N]:1、申请数组大小个对象的空间operator new[] -> operator new -> malloc 。2、调用数组大小次对象构造函数
delete[] :1、调用析构。 2、operator delete[] -> operator delete-> free
通常,new负责在(heap)中找到一个足以满足要求的内存块。new运算符还有另一种变体,被称为定位(placement)new运算符,它能让您指定要是有的位置。程序员可能使用这种特性来设置其内存管理规程、处理需要通过特定地址进行访问的硬件或在特定位置创建对象。
要使用定位new特性,首先需要包含头文件new,它提供了这种版本的new运算符的原型;然后将new运符用于提供了所需地址的参数。除需要指定参数外,句法与常规 new 运算符相同。具体地说,使用定位 new 运算符时,变量后面可以有方括号,也可以没有。
//使用格式 new (place_address) type; new (place_address) type(initializer-list) ;
place_address必须是一个指针,initializer-list是类型的初始化列表。
下面一段代码演示了new运算符的4种用法。
#include<new> struct chaff { char dross[20]; int slag; }; char buffer1[50]; char buffer2[500]; int main() { chaff* p1, * p2; int* p3, * p4; //普通new p1 = new chaff; p3 = new int[20]; //定位new p2 = new (buffer1)chaff; p3 = new (buffer2)int[20]; return 0; }
出于简化的目的,这个示例使用两个静态数组来定位new运算符提供内存空间。因此,上述代码从buffer1这分配空间给结构chaff,从buffer2中分配空间给一个包含20个元素的int数组。
A* p = (A*)operator new (sizeof(A)); new(p)A();//定位new表达式
定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化。
malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地方是:
malloc和free是函数,new和delete是操作符
malloc申请的空间不会初始化,new可以初始化
malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可, 如果是多个对象,[]中指定对象个数即可
malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需 要捕获异常
申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new 在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成 空间中资源的清理
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。