首页 > 编程知识 正文

动态内存分配三种方式,c语言的内存空间储存

时间:2023-05-06 10:07:29 阅读:146380 作者:2351

[size=medium]1. malloc ()函数

1.1 malloc的全名是内存分配,在中文中称为动态内存分配。

原型: extern void * malloc (unsigned intnum _ bytes );

说明:分配长度为num_bytes字节的内存块。 分配成功时返回指向分配内存的指针,分配失败时返回空指针。 如果内存不再使用,则必须使用free ()函数释放内存块。

1.2void*malloc(intsize );

说明: malloc向系统申请分配指定size字节的内存空间。 返回类型为void*类型。 void*表示未确定类型的指针。 c、c规定,void*类型可以强制转换为其他类型的指针。

注: void*是指未确定类型的指针。 更明确地说,这意味着用户不知道使用该区域存储什么类型的数据。 例如,char还是int . )

1.3自由

voidfree(void*firstbyte ) :此函数将以前在malloc中分配的空间返回给程序或操作系统,也就是说释放此内存,以便重新获得自由。

1.4注意事项

1 )申请内存空间后,应检查分配是否成功。

2 )如果不需要重新使用申请的内存,则在记住释放它的发行后,必须将指向此内存的指针留空,以避免在程序后面意外使用。

3 )这两个函数应该配对。 如果申请后不被释放,就是内存泄露。如果无故被释放,就等于什么也没做。 发行版本只有一次,如果发行两次以上就会发生错误(发行空指针除外,因为发行空指针与实际上什么都没做一样,所以发行空指针或多次发行都没有问题)

4 ) malloc ) )函数的类型为(void * ),可以转换为任何类型的指针() void * ),但最好在此之前强制执行类型转换,因为这样可以避免编译器检查。

1.5 malloc ) )到底从哪里得到内存空间的?

答案是从山里得到空间。 这意味着函数返回的指针指向堆中的内存。 操作系统具有一个链表,用于记录空闲内存地址。 当操作系统收到程序请求时,它遍历该链表,查找第一个空间大于请求空间的堆节点,并从空闲节点的链表中删除该节点,然后返回该节点中的

2. new运算符

在2.1 C中,数组或单个对象在new和delete中动态创建和释放。

动态创建对象时,只需指定数据类型,而不是命名对象。 new表达式返回指向新创建对象的指针,可以通过指针访问。

int *pi=new int;

此new表达式创建为堆空间分配的整数对象,返回此对象的地址,并使用此地址初始化指针pi。

2.2初始化动态创建对象

动态创建的对象可以用初始化变量初始化。

int*pi=newint(100; //指针pi指向的对象被初始化为100

string*PS=newstring(10,’9’); //*ps为“9999999999”

如果没有提供显示初始化,则针对类类型,用该类的默认构造函数进行初始化; 不会初始化内置类型的对象。

也可以初始化动态创建的对象的值。

int *pi=new int (; 初始化为//0

int *pi=new int; //pi指向未初始化的int

string *ps=new string (; //初始化为空字符串(提供缺省构造函数的类类型不需要初始化对象的值) )。

2.3撤消动态创建的对象

delete表达式释放指针指向的地址空间。

删除pi; //释放单个对象

delete [ ]pi; //释放数组

如果指针未指向new分配的内存地址,则使用delete是不合法的。

2.4删除后,重置指针值

delete p; //执行此语句后,p变为不确定指针,并且许多机器存储了在此之前指定的对象的地址,尽管p的值没有明确定义。 并且,由于p指向的内存被释放了,所以p不再有效。 此时,该指针将成为悬垂指针。 悬垂指针指向存储对象的内存,但对象已不存在。 悬垂指针经常引起程序错误,很难检测到。

删除指针指向的对象后,立即将指针设置为0。 这可以明确指针不指向哪个对象。 (零值指针: int *ip=0; )

2.5区分零指针和空指针

零值指针可以是值为0的指针,可以是任何指针类型,可以是通用变型void*,也可以是char*,int*等。

空指针实际上是一个编程概念,空指针是人工识别的指针,因为容器可能有两种基本状态:空和非空,否则可能存储0的值参考: http://www.cn blogs.com/tw DPJ 1988 happy/archive/2012/04/16/2452021.html

2.6如果new分配失败,会返回什么?

在1993年之前,c要求operator new在内存分配失败时返回0,但现在要求operator new抛出s

td::bad_alloc异常。很多c++程序是在编译器开始支持新规范前写的。c++标准委员会不想放弃那些已有的遵循返回0规范的代码,所以他们提供了另外形式的operator new(以及operator new[])以继续提供返回0功能。这些形式被称为“无抛出”,因为他们没用过一个throw,而是在使用new的入口点采用了nothrow对象:
class widget { ... };

widget *pw1 = new widget;// 分配失败抛出std::bad_alloc

if (pw1 == 0) ... // 这个检查一定失败

widget *pw2 = new (nothrow) widget; // 若分配失败返回0

if (pw2 == 0) ... // 这个检查可能会成功

3. malloc和new的区别

3.1 new 返回指定类型的指针,并且可以自动计算所需要大小。
比如:   
1) int *p;   
p = new int; //返回类型为int* 类型(整数型指针),分配大小为 sizeof(int);   
或:   
int* parr;   
parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100;   
2) 而 malloc 则必须要由我们计算字节数,并且在返回后强行转换为实际类型的指针。   
int* p;   
p = (int *) malloc (sizeof(int)*128);//分配128个(可根据实际需要替换该数值)整型存储单元,并将这128个连续的整型存储单元的首地址存储到指针变量p中
double *pd=(double *) malloc (sizeof(double)*12);//分配12个double型存储单元,并将首地址存储到指针变量pd中

3.2 malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。
除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。

4.有了malloc/free为什么还要new/delete?

1) malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。
2) 对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。
我们不要企图用malloc/free来完成动态对象的内存管理,应该用new/delete。由于内部数据类型的“对象”没有构造与析构的过程,对它们而言malloc/free和new/delete是等价的。
3) 既然new/delete的功能完全覆盖了malloc/free,为什么C++不把malloc/free淘汰出局呢?这是因为C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。
如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc申请的动态内存”,结果也会导致程序出错,但是该程序的可读性很差。所以new/delete必须配对使用,malloc/free也一样。[/size]
转自:http://www.cnblogs.com/twdpj1988happy/archive/2012/04/26/2470542.html

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。