C++二维数组动态分配内存存和释放

C++中动态分配、释放内存的问题
[问题点数:50分,结帖人bluescorpio]
C++中动态分配、释放内存的问题
[问题点数:50分,结帖人bluescorpio]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2012年7月 Java大版内专家分月排行榜第三2011年11月 Java大版内专家分月排行榜第三2007年12月 Java大版内专家分月排行榜第三2007年10月 Java大版内专家分月排行榜第三
2012年7月 Java大版内专家分月排行榜第三2011年11月 Java大版内专家分月排行榜第三2007年12月 Java大版内专家分月排行榜第三2007年10月 Java大版内专家分月排行榜第三
匿名用户不能发表回复!|We are drowning in information and starving for knowledge.
&&&&&& 动态分配可以说是指针的关键所在。不需要通过定义变量,就可以将指针指向分配的内存。也许这个概念看起来比较模糊,但是确实比较简单。下面的代码示范如何为一个整数分配内存:
pNumber = new int;
&&&&&& 第一行申明了一个指针pNumber,第二行分配一个整数内存,并且将pNumber指向这个新内存。下面是另一个例子,这次用一个浮点数:
double *pD
pDouble = new double;
&&&&&& 动态分配有什么不同的呢?当函数返回或者程序运行到当前块以外时,你动态分配的内存将不会被删除。因此,如果我们用动态分配重写上面的例子,可以看到现在能够正常工作了。
#i nclude &stdio.h&
void SomeFunction()
// make pPointer point to a new integer
pPointer = new int;
*pPointer = 25;
void main()
SomeFunction(); // make pPointer point to something
printf("Value of *pPointer: %d/n", *pPointer);
&&&&&& 通读一遍,编译上面的代码,确信你已经理解它是如何工作的。当调用SomeFunction时,分配了一些内存,并且用pPointer指向它。这次,当函数返回时,新内存就完整无缺了。因此pPointer仍旧指向有用的东西。这是因为使用了动态分配。确信你已经理解它了。那么继续向下看,了解为什么上面的程序还会有一系列的错误。
内存分配和内存释放
这里有一个问题,可能会变得十分严重,虽然它很容易补救。这个问题就是,虽然你用动态分配可以方便的让内存完整无缺,确实不会自动删除,除非你告诉计算机,你不再需要这块内存了,否则内存将一直被分配着。因此结果就是,如果你不告诉计算机你已经使用完这块内存,那么它将成为被浪费的空间,因为其它程序或者你的应用程序的其它部分不能使用这块内存。最终将导致系统因为内存耗尽而崩溃。因此这个问题相当重要。内存使用完后释放非常容易:
&&&&&& 需要做的就是这些。但是你必须确定,你删除的是一个指向你实际分配的内存的指针,而不是其它任何垃圾。尝试用delete已经释放的内存是危险的,并且可能导致程序崩溃。
&&&&&& 这里再次举个例子,这次修改以后就不会有内存浪费了。
#include &stdio.h&
void SomeFunction()
// make pPointer point to a new integer
pPointer = new int;
*pPointer = 25;
void main()
SomeFunction(); // make pPointer point to something
printf("Value of *pPointer: %d/n", *pPointer);
只有一行不同,但这行是要点。如果你不删除内存,就会导致&内存泄漏&,内存将逐渐减少,除非应用程序重新启动,否则将不能再生。
阅读(...) 评论() &博呀博呀博呀客
C++ new动态分配内存和delete释放内存
C++中使用简便而强大的new和delete运算符来进行动态内存的分配.
值得注意的是,new和delete和c语言中的malloc和free不同,new和delete是运算符,因此执行效率更高.
如何使用new , delete 呢?
首先我们来看一段代码:
我们可以看到有那些元素.
首先是int, 它的含义是声明指针类型;
其次是*p, p是指针变量(注意,指针也是一种变量,可以理解为它的类型为int *)名.
= 是赋值符号,为什么是赋值符号呢?因为后面一段代码返回的是一个地址,地址赋给了p
new int 是什么意思呢?new是一种运算符,它返回的是一种数据类型的内存地址.
一般格式如下:
new typename (value)
所以,之前那一段代码也可以拆分为:
如果想给 *p 赋值,应该这样
int *p = new int (12);
这是最基本的声明动态变量方法.
如何用new来声明数组? 首先介绍一维数组:
int *p = new int[4];
和上面不同的是,这段代码后面是 [4],这意味着什么呢?
这意味着new了一个数组元素数为4的一维数组.
OK,任务完成. 可是,细心的小伙伴可能会发现,这样的话, 上面提到给变量赋值的(value)怎么办呢?放在哪呢?
事实上,C++不支持在动态分配数组内存的时候给数组赋初值.所以,想要赋初值,只能自己写个循环语句赋过去咯.
一维数组是这样,那么二维乃至多维呢?
二维可以这样:
int (*p)[3] = new int [4][3];
这样就动态声明了一个行是4, 列是3的数组.
值得注意的是,在此代码 [3] 这个位置,"3"的值可以是常量(1,2...),或者const常量,不能是变量.(表示被坑过) "4"处,可以是变量
还有另一种声明方式:
int **p = new int *[n];
for( int i=0;i&n;++i ) {
p[i] = new int [m];
这样就生成了行为n, 列为m的二维数组了.
这样的方法较前一种复杂些,但m, n都可以是变量.
可以这么理解:先生成了一个以为数组,然后再在每个元素的位置生成一个一维数组,这样,一个二维数组就这样建立起来了.
同样,参照这种方法,可以建立多维数组.
new讲完了,那么delete呢?
delete的作用不做赘述, 我们只讲各种形式如何delete.
int *p = new int(1);
这两种delete是一样的
int *p = new int [4];
这是一维数组,所以delete的方式有些不同
delete []p;
只有[]的不同:[]告诉程序,应释放整个数组,而不仅是指针指向的元素.
二维数组呢?
for( int i=0;i&n;++i )
delete [] p[i];
不要用delete来释放同一个内存两次,程序运行会出错.
不要用delete来释放不是new分配的内存
对空指针应用delete是安全的.
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!C/C++动态分配与释放内存的区别详细解析_C 语言
作者:用户
本文讲的是C/C++动态分配与释放内存的区别详细解析_C 语言,
1. malloc()函数1.1 malloc的全称是memory allocation,中文叫动态内存分配。原型:extern void *malloc(unsigned int num_bytes); 说明:分配长度为num_byte
1. malloc()函数1.1 malloc的全称是memory allocation,中文叫动态内存分配。原型:extern void *malloc(unsigned int num_bytes); 说明:分配长度为num_bytes字节的内存块。如果分配成功则返回指向被分配内存的指针,分配失败返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。
1.2 void *malloc(int size); 说明:malloc 向系统申请分配指定size个字节的内存空间,返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。   备注:void* 表示未确定类型的指针,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者...)
1.3 freevoid free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。
1.4注意事项1)申请了内存空间后,必须检查是否分配成功。
2)当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。
3)这两个函数应该是配对。如果申请后不释放就是内存泄露;如果无故释放那就是什么也没有做。释放只能一次,如果释放两次及两次以上会出现错误(释放空指针例外,释放空指针其实也等于啥也没做,所以释放空指针释放多少次都没有问题)。4)虽然malloc()函数的类型是(void *),任何类型的指针都可以转换成(void *),但是最好还是在前面进行强制类型转换,因为这样可以躲过一些编译器的检查。
malloc()到底从哪里得到了内存空间?答案是从堆里面获得空间。也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。
2. new运算符
2.1 C++中,用new和delete动态创建和释放数组或单个对象。动态创建对象时,只需指定其数据类型,而不必为该对象命名,new表达式返回指向该新创建对象的指针,我们可以通过指针来访问此对象。int *pi=这个new表达式在堆区中分配创建了一个整型对象,并返回此对象的地址,并用该地址初始化指针pi 。
2.2 动态创建对象的初始化动态创建的对象可以用初始化变量的方式初始化。int *pi=new int(100); //指针pi所指向的对象初始化为100string *ps=new string(10,'9');//*ps 为“”
如果不提供显示初始化,对于类类型,用该类的默认构造函数初始化;而内置类型的对象则无初始化。也可以对动态创建的对象做值初始化:int *pi=new int( );//初始化为0int *pi=//pi 指向一个没有初始化的intstring *ps=new string( );//初始化为空字符串 (对于提供了默认构造函数的类类型,没有必要对其对象进行值初始化)
2.3 撤销动态创建的对象delete表达式释放指针指向的地址空间。// 释放单个对象delete [ ]//释放数组如果指针指向的不是new分配的内存地址,则使用delete是不合法的。
2.4 在delete之后,重设指针的值 //执行完该语句后,p变成了不确定的指针,在很多机器上,尽管p值没有明确定义,但仍然存放了它之前所指对象的地址,然后p所指向的内存已经被释放了,所以p不再有效。此时,该指针变成了悬垂指针(悬垂指针指向曾经存放对象的内存,但该对象已经不存在了)。悬垂指针往往导致程序错误,而且很难检测出来。一旦删除了指针所指的对象,立即将指针置为0,这样就非常清楚的指明指针不再指向任何对象。(零值指针:int *ip=0;)
2.5 区分零值指针和NULL指针零值指针,是值是0的指针,可以是任何一种指针类型,可以是通用变体类型void*也可以是char*,int*等等。空指针,其实空指针只是一种编程概念,就如一个容器可能有空和非空两种基本状态,而在非空时可能里面存储了一个数值是0,因此空指针是人为认为的指针不提供任何地址讯息。
2.6 new分配失败时,返回什么?1993年前,c++一直要求在内存分配失败时operator
new要返回0,现在则是要求operator
new抛出std::bad_alloc异常。很多c++程序是在编译器开始支持新规范前写的。c++标准委员会不想放弃那些已有的遵循返回0规范的代码,所以他们提供了另外形式的operator
new(以及operator
new[])以继续提供返回0功能。这些形式被称为“无抛出”,因为他们没用过一个throw,而是在使用new的入口点采用了nothrow对象: class
分配失败抛出std::bad_alloc
这个检查一定失败
若分配失败返回0
这个检查可能会成功
3. malloc和new的区别
3.1 new 返回指定类型的指针,并且可以自动所需要大小。比如:   1) int *p;   p = //返回类型为int* 类型(整数型指针),分配大小为 sizeof(int);   或:   int*   parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100;   
2) 而 malloc 则必须要由我们计算字节数,并且在返回后强行转换为实际类型的指针。   int*   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也一样。
以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索内存分配
详细设计 存储分配、如何释放dhcp分配的ip、考研分数详细分配、主存分配与释放、虚拟内存的分配与释放,以便于您获取更多的相关知识。
弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率
40+云计算产品,6个月免费体验
稳定可靠、可弹性伸缩的在线数据库服务,全球最受欢迎的开源数据库之一
云服务器9.9元/月,大学必备
云栖社区(yq.aliyun.com)为您免费提供相关信息,包括
,所有相关内容均不代表云栖社区的意见!C++ 动态内存
了解动态内存在 C++ 中是如何工作的是成为一名合格的 C++ 程序员必不可少的。C++ 程序中的内存分为两个部分:
栈:在函数内部声明的所有变量都将占用栈内存。
堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。
很多时候,您无法提前预知需要多少内存来存储某个定义变量中的特定信息,所需内存的大小需要在运行时才能确定。
在 C++ 中,您可以使用特殊的运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。这种运算符即 new 运算符。
如果您不再需要动态分配的内存空间,可以使用 delete 运算符,删除之前由 new 运算符分配的内存。
new 和 delete 运算符
下面是使用 new 运算符来为任意的数据类型动态分配内存的通用语法:
在这里,data-type 可以是包括数组在内的任意内置的数据类型,也可以是包括类或结构在内的用户自定义的任何数据类型。让我们先来看下内置的数据类型。例如,我们可以定义一个指向 double 类型的指针,然后请求内存,该内存在执行时被分配。我们可以按照下面的语句使用 new 运算符来完成这点:
double* pvalue = NULL;
pvalue = new double;
如果自由存储区已被用完,可能无法成功分配内存。所以建议检查 new 运算符是否返回 NULL 指针,并采取以下适当的操作:
double* pvalue = NULL;
if( !(pvalue = new double ))
cout && &Error: out of memory.& &&endl;
malloc() 函数在 C 语言中就出现了,在 C++ 中仍然存在,但建议尽量不要使用 malloc() 函数。new 与 malloc() 函数相比,其主要的优点是,new 不只是分配了内存,它还创建了对象。
在任何时候,当您觉得某个已经动态分配内存的变量不再需要使用时,您可以使用 delete 操作符释放它所占用的内存,如下所示:
// 释放 pvalue 所指向的内存
下面的实例中使用了上面的概念,演示了如何使用 new 和 delete 运算符:
#include &iostream&
using namespace std;
int main ()
double* pvalue = NULL;
pvalue = new double;
*pvalue = 29494.99;
cout && &Value of pvalue : & && *pvalue && endl;
delete pvalue;
当上面的代码被编译和执行时,它会产生下列结果:
Value of pvalue : 29495
数组的动态内存分配
假设我们要为一个字符数组(一个有 20 个字符的字符串)分配内存,我们可以使用上面实例中的语法来为数组动态地分配内存,如下所示:
char* pvalue
// 初始化为 null 的指针
= new char[20]; // 为变量请求内存
要删除我们刚才创建的数组,语句如下:
// 删除 pvalue 所指向的数组
下面是 new 操作符的通用语法,可以为多维数组分配内存,如下所示:
int *array=new int [m];
delete [] array;
int **array
array = new int *[m];
for( int i=0; i&m; i++ )
array[i] = new int [n] ;
for( int i=0; i&m; i++ )
delete [] arrar[i];
delete [] array;
二维数组实例测试:
#include &iostream&
using namespace std;
int main()
p = new int *[4];
for(i=0;i&4;i++){
p[i]=new int [8];
for(i=0; i&4; i++){
for(j=0; j&8; j++){
p[i][j] = j*i;
for(i=0; i&4; i++){
for(j=0; j&8; j++)
if(j==0) cout&&endl;
cout&&p[i][j]&&&\t&;
for(i=0; i&4; i++){
delete [] p[i];
delete [] p;
int ***array;
array = new int **[m];
for( int i=0; i&m; i++ )
array[i] = new int *[n];
for( int j=0; j&n; j++ )
array[i][j] = new int [h];
for( int i=0; i&m; i++ )
for( int j=0; j&n; j++ )
delete array[i][j];
delete array[i];
delete [] array;
三维数组测试实例:
#include &iostream&
using namespace std;
int main()
int i,j,k;
p = new int **[2];
for(i=0; i&2; i++)
p[i]=new int *[3];
for(j=0; j&3; j++)
p[i][j]=new int[4];
for(i=0; i&2; i++)
for(j=0; j&3; j++)
for(k=0;k&4;k++)
p[i][j][k]=i+j+k;
cout&&p[i][j][k]&&& &;
cout&&endl;
cout&&endl;
for(i=0; i&2; i++)
for(j=0; j&3; j++)
delete [] p[i][j];
for(i=0; i&2; i++)
delete [] p[i];
delete [] p;
对象的动态内存分配
对象与简单的数据类型没有什么不同。例如,请看下面的代码,我们将使用一个对象数组来理清这一概念:
#include &iostream&
using namespace std;
cout && &调用构造函数!& &&endl;
cout && &调用析构函数!& &&endl;
int main( )
Box* myBoxArray = new Box[4];
delete [] myBoxArray;
如果要为一个包含四个 Box 对象的数组分配内存,构造函数将被调用 4 次,同样地,当删除这些对象时,析构函数也将被调用相同的次数(4次)。
当上面的代码被编译和执行时,它会产生下列结果:
调用构造函数!
调用构造函数!
调用构造函数!
调用构造函数!
调用析构函数!
调用析构函数!
调用析构函数!
调用析构函数!
10个月前 (08-07)
感谢您的支持,我会继续努力的!
扫码打赏,你说多少就多少
记住登录状态
重复输入密码

我要回帖

更多关于 netty 内存分配释放 的文章

 

随机推荐