动态内存创建与释放

mac2025-11-06  20

一.申请动态内存

申请动态内存:malloc/calloc/realloc,申请的动态内存分为多少份此函数无法明确,所以应在malloc/calloc/realloc前面加上类型

1.malloc

malloc函数的形参为所要申请的动态内存字节数(动态数组总共所占字节数),若申请成功,此函数会将申请的动态连续内存(动态数组)的首地址返回,申请失败返回空指针。

例如:int *p1=(int *)malloc(20); //申请20个字节的内存,类型为int 每个int所占字节数为4,所以此数组可放5个int变量

free(p1); //释放掉这20个字节的内存 int *p2=(double *)malloc(32); //申请32个字节的内存,类型为double 每个double所占字节数为8,所以此数组可放5个double变量 free(p2); int *p3=(char *)malloc(10); //申请10个字节的内存,类型为char 每个char所占字节数为1,所以此数组可放10个char变量 free(p3);

动态内存在堆里,它突破了局部变量的作用域和生存期,如果申请动态内存成功,只有free函数或程序运行结束,否则此段内存始终可以使用,它突破局部变量的作用域和生存期。 #include <stdio.h> #include <stdlib.h>

int *show1() { int arr1[]={0,1,2,3,4}; return arr1; } int *show2() { int *arr2=(int )malloc(5sizeof(int)); for(int i=0;i<5;i++) { arr2[i]=i; } return arr2; }

int main() { int *p1=show1(); int i; for(i=0;i<5;i++) { printf(“p1[%d]=%d “,i,p1[i]); } printf(”\n\n\n\n\n”); int *p2=show2(); for(i=0;i<5;i++) { printf("p2[%d]=%d ",i,p2[i]); } free(p2);

return 0;

} 2.calloc

calloc(数组长度,数组每一个单元格所占字节数)

calloc与malloc区别:申请的动态数组会初始化为0;

例: #include <stdio.h> #include <stdlib.h>

int main() {

int *arr1= (int *)malloc(10*sizeof(int)); int i; for(i=0;i<10;i++) { arr1[i] = 0; } for(i=0;i<10;i++) { printf("arr1[%d]=%d ",i,arr1[i]); } printf("\n\n\n\n"); //等同以下操作 int *arr2 = (int *)calloc(10,sizeof(int));//10为数组长度,每一个单元格占4字节 for(i=0;i<10;i++) { printf("arr2[%d]=%d ",i,arr2[i]); } free(arr1); free(arr2); return 0;

} 3.realloc

修改动态数组的大小。

当扩大动态数组的大小时,会重新申请一块内存(此时所需要的内存总字节数),再将旧内存中的内容复制到新的内存中,释放掉旧内存,将新内存的首地址赋给保存旧内存首地址的指针,将申请新内存时保存新首地址的指针置空。

当缩小动态内存的大小时,无操作。

realloc(旧内存的首地址,此时所需要的内存总字节数);

例:

1.扩大动态内存:

#include <stdio.h> #include <stdlib.h>

int main() {

int *p1 = (int *)malloc(10*sizeof(int));//先申请10个长度(共40字节)整型动态数组 int i; for(i=0;i<10;i++) { p1[i] = 10*i; } p1 = (int *)realloc(p1,20*sizeof(int));//将动态数组的长度修改为20(共80字节) for(i=0;i<10;i++) { printf("p1[%d]=%d ",i,p1[i]); } free(p1); printf("\n\n\n\n\n"); //下面的代码等同realloc int *p2 = (int *)malloc(10*sizeof(int)); for(i=0;i<10;i++) { p2[i] = 10*i; } int *q = (int *)malloc(20*sizeof(int)); for(i=0;i<10;i++) { q[i] = p2[i]; } p2 = q; q = NULL; for(i=0;i<10;i++) { printf("p2[%d]=%d ",i,p2[i]); } free(p2); return 0;

}

2.缩小动态内存 #include <sdio.h> #include <stdlib.h>

int main() { int p = (int )malloc(10sizeof(int)); int i; for(i=0;i<10;i++) { p[i] = 10i; } printf(“缩小内存前%d\n”,p); for(i=0;i<10;i++) { printf(“p[%d]=%d “,i,p[i]); } printf(”\n\n\n\n\n”); p = (int )realloc(p,5sizeof(int)); printf(“缩小内存后%d\n”,p); for(i=0;i<10;i++) { printf(“p[%d]=%d “,i,p[i]); } free§; printf(”\n释放动态内存后%d\n”,p); return 0; } 二.释放动态内存

释放动态内存:free

free(动态内存首地址)

使用完动态内存后要用free释放掉申请的动态内存,否则会造成内存泄漏(可使用的内存越来越少),释放掉动态内存后要将保存原动态内存首地址的指针置空,此时此段内存已被操作系统回收,这个指针为野指针。

free崩溃的原因:

1.越界

例: int main() { int *p = (int )malloc(10sizeof(int)); for(int i=0;i<=10;i++) //应为i<10 { p[i] = 0; } free§; return 0; } 2.修改指针指向

例; int main() { int *p = (int )malloc(10sizeof(int)); for(int i=0;i<10;i++) { *p = 0; p++; //p的指向改变 } free§; return 0; } 3.重复释放同一段内存

例; int main() { int *p = (int )malloc(10sizeof(int)); for(int i=0;i<10;i++) { p[i] = i; } int *q = (int )malloc(20sizeof(int)); for(int i=0;i<10;i++) { q[i] = p[i]; } free§; p = q;

free(p); free(q);// 应将q = NULL; return 0;

} 4.释放非动态内存

例: int main() { int arr[10]; free(arr);

return 0;

}

最新回复(0)