动态指针数组,释放内存问题

上传人:子 文档编号:41822945 上传时间:2018-05-31 格式:DOC 页数:11 大小:37.50KB
返回 下载 相关 举报
动态指针数组,释放内存问题_第1页
第1页 / 共11页
动态指针数组,释放内存问题_第2页
第2页 / 共11页
动态指针数组,释放内存问题_第3页
第3页 / 共11页
动态指针数组,释放内存问题_第4页
第4页 / 共11页
动态指针数组,释放内存问题_第5页
第5页 / 共11页
点击查看更多>>
资源描述

《动态指针数组,释放内存问题》由会员分享,可在线阅读,更多相关《动态指针数组,释放内存问题(11页珍藏版)》请在金锄头文库上搜索。

1、动态指针数组动态指针数组, ,释放内存问题释放内存问题c 语言中内存的动态分配与释放(多维动态数组构建) (2012-02-29 00:17) 标签: c 语言 内存 动态 分类: C/C+ 一. 静态数组与动态数组静态数组比较常见,数组长度预先定义好,在整个程序中,一旦给定大小后就无法再改变长度,静态数组自己自动负责释放占用的内存。动态数组长度可以随程序的需要而重新指定大小。动态数组由内存分配函数(malloc)从堆(heap)上分配存储空间,只有当程序执行了分配函数后,才为其分配内存,同时由程序员自己负责释放分配的内存(free) 。二. 为什么要使用动态数组?在实际的编程中,往往会发生这

2、种情况,即所需的内存空间取决于实际输入的数据,而无法预先确定。对于这种问题,用静态数组的办法很难解决。为了解决上述问题,c 语言提供了一些内存管理函数,这些内存管理函数结合指针可以按需要动态地分配内存空间,来构建动态数组,也可把不再使用的空间回收待用,为有效地利用内存资源提供了手段。三. 动态数组与静态数组的比较对于静态数组,其创建非常方便,使用完也无需释放,要引用也简单,但是创建后无法改变其大小是其致命弱点! 对于动态数组,其创建麻烦,使用完必须由程序员自己释放,否则严重会引起内存泄露。但其使用非常灵活,能根据程序需要动态分配大小。四. 如何构建动态数组?构建动态数组时,我们遵循下面的原则:

3、申请的时候从外层往里层,逐层申请;释放的时候从里层往外层,逐层释放;五. 构建动态数组所需指针对于构建一维动态数组,需要一维指针; 对于二维,则需要一维,二维指针; 对于三维,需要一,二,三维指针; 依此类推。六. 动态内存分配与释放函数1. /*动态内存分配与释放函数*/2. void *malloc(unsigned int size);3. void *calloc(unsigned int num, unsigned int size); 4. void *realloc(void *p,unsigned int size); 5. void free(void *p);说明:(1)m

4、alloc()函数成功:返回所开辟空间首地址;失败:返回空指针;功能:向系统申请 size 字节堆的空间;calloc()成功:返回所开辟空间首地址;失败:返回空指针;功能:按类型向系统申请 num 个 size 字节堆的空间;realloc()成功:返回所开辟空间首地址;失败:返回空指针;功能:将 p 指向的空间变为个 size 字节堆的空间;free()没有返回值,释放 p 指向的堆空间;(2) 规定为 void *类型,这并不是说该函数调用后无返回值,而是返回一个结点的地址,该地址的类型为 void(无类型或类型不确定),即一段存储区的首址,其具体类型无法确定,只有使用时根据各个域值数据

5、再确定。可以用强制转换的方法将其转换为别的类型。例如:1. double *pd = NULL; 2. pd = (double *)calloc(10, sizeof(double);表示将向系统申请 10 个连续的 double 类型的存储空间,并用指针pd 指向这个连续的空间的首地址。并且用(double)对 calloc()的返回类型进行转换,以便把 double 类型数据的地址赋值给指针 pd。(3)使用 sizeof 的目的是用来计算一种类型的占有的字节数,以便适合不同的编译器。(4)检查动态内存是否分配成功由于动态分配不一定成功,为此要附加一段异常处理程序,不致程序运行停止,使用

6、户不知所措。通常采用这样的异常处理程序段:1. if (p = NULL) /* 或者 if(!p)*/ 2. 3. printf(“动态申请内存失败!n“);4. exit(1); /异常退出 5. (5)这四个函数头文件均包含在中。 (6)分配的堆空间是没有名字的,只能通过返回的指针找到它。 (7)绝不能对非动态分配存储块使用 free。也不能对同一块内存区同时用 free 释放两次,如:1. free(p);2. free(p);(8)调用 free()时, 传入指针指向的内存被释放, 但调用函数的指针值可能保持不变, 因为 p 是作为形参而传递给了函数。严格的讲, 被释放的指针值是无效

7、的, 因为它已不再指向所申请的内存区。这时对它的任何使用便可能会可带来问题。所以在释放一个指针指向的内存后,将该指针赋值为 0,避免该指针成为野指针:1. int *p = (int *)malloc(sizeof(int);2. free(p); /*释放 p 指向内存*/3. p = 0; /*或者 p = NULL,释放 p 指向的内存后,将 p 指针赋值为 0,避免 p 指针成为野指针*/(9)malloc 与 calloc 的区别,对于用 malloc 分配的内存区间,如果原来没有被使用过,则其中的每一位可能都是 0;反之,如果这部分内存空间曾经被分配、释放和重新分配,则其中可能遗留

8、各种各样的数据。也就是说,使用 malloc()函数的程序开始时(内存空间还没有被重新分配)能正常运行,但经过一段时间后(内存空间已被重新分配)可能会出现问题,因此在使用它之前必须先进行初始化(可用 memset 函数对其初始化为 0) ,但调用 calloc()函数分配到的空间在分配时就已经被初始化为 0 了。当你在 calloc()函数和malloc()函数之间作选择时,你需考虑是否要初始化所分配的内存空间,从而来选择相应的函数。六.动态数组构建过程以三维整型数组为例 int arrayxyz先遵循从外到里,逐层申请的原则:最外层的指针就是数组名 array,他是一个三维指针,指向的是ar

9、ray,array是二维指针,所以给 array 申请内存空间需要一个三维指针 int * p;1. /*给三维数组 arrayxyz动态分配内存*/2. int * p = (int *)malloc(x * sizeof(int *); 3. /*或者如下*/ 4. array = (int *)malloc(x * sizeof(int *)5. /*指针 p 指向的是 array 三维数组的第一维,有 x 个元素,所以要 sizeof(x * (int *)*/次层指针是 array,它是一个二维指针,指向的是 array,array是一维指针:1. int i, j;2. for (

10、i = 0; i 7. #include 8.9. void Malloc3DActiveArray(int * pArr, int x, int y, int z);10.void Free3DActiveArray(int * pArr, int x, int y);11./void Display3DArray(int * pArr, int x, int y, int z);12.13.14.int main(void)15.16.int x, y, z;17.int * array = NULL;18.19.printf(“输入一维长度: “);20.scanf(“%d“,21.pr

11、intf(“输入二维长度: “);22.scanf(“%d“,23.printf(“输入三维长度: “);24.scanf(“%d“,25.26.Malloc3DActiveArray(array, x, y, z);27.Free3DActiveArray(array, x, y);28.array = NULL;29.30.return 0;31.32.33.void Malloc3DActiveArray(int * pArr, int x, int y, int z)34.35.int i, j, k;36.pArr = (int *)malloc(x * sizeof(int *);

12、37.38.for (i = 0; i 7. #include 8.9. int main()10.11.int n1,n2,n3,n4;12.int *array;13.int i,j,k,m;14.15.puts(“输入一维长度:“);16.scanf(“%d“,17.puts(“输入二维长度:“);18.scanf(“%d“,19.puts(“输入三维长度:“);20.scanf(“%d“,21.puts(“输入四维长度:“);22.scanf(“%d“,23.24.array = (int *)malloc(n1 * sizeof(int*);/第一维25.26.for (i = 0;

13、 i n1; i+)27.28.arrayi = (int*)malloc(n2 * sizeof(int*); /第二维29.for (j = 0; j n2; j+)30.31.arrayij = (int*)malloc(n3 * sizeof(int*); /第三维32.for (k = 0; k n3; k+)33.34.arrayijk = (int *)malloc(n4 * sizeof(int);/第四维35.for (m = 0; m n4; m+)36.37.arrayijkm = i + j + k + m + 1;38.printf(“%dt“, arrayijkm)

14、;39.40.printf(“n“);41.42.printf(“n“);43.44.printf(“n“);45.46.47.for (i = 0; i n1; i+)48.49.for (j = 0; j n2; j+)50.51.for (k = 0; k n3; k+)52.53.free(arrayijk);/释放第四维指针54.arrayijk = 0;55.56.57.free(arrayij);/释放第三维指针58.arrayij = 0;59.60.61.free(arrayi);/释放第二维指针62.arrayi = 0;63.64.65.free(array);/释放第一维指针66.array = NULL;67.68.return 0;69.70.71./*72.在 vc+6.0 中输出结果为:73.-74.输入一维长度:75.176.输入二维长度:77.278.输入三维长度:79.380.输入四维长度:81.482.1 2 3 483.2 3 4 584.3 4 5 685.86.2 3 4 587.3 4 5 688.4 5 6 789.Press any key to continue

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号