C语言内存管理主要包括malloc()、remalloc()、free()三个函数。
malloc原型 extern void *malloc(unsigned int num_bytes);
m行n列的 二维数组的分配,主要有三种方法:
一、分配一个长度为m的二级指针,指针的指向的内容分别指向一个长度为n的一位数组
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> //二维数组内存分配 int main() { int i,j,c=0; int m,n; int **p; int *head; scanf("%d %d",&m,&n); p=(int **)malloc(sizeof(int *)*m); if (p==NULL) { puts("memory allocation error!"); return; } //head=(int *)p+m; //指向数据内容起始的首地址 //memset(p,0,sizeof(int *)*m+sizeof(int)*m*n); //内存区域清零 for (i=0;i<m;i++) { //p[i]=head+(i*n); //both is ok *(p+i)=(int *)malloc(sizeof(int)*n); } for(i=0;i<m;i++) { for (j=0;j<n;j++) { *(*(p+i)+j)=c++; } } for(i=0;i<m;i++) { for (j=0;j<n;j++) { printf("%x: %4d\t",&p[i][j],p[i][j]); } printf("\n"); } for (i=0;i<m;i++) { free(p[i]); } free(p); system("pause"); return 0; }
二、分配一个长度为m*n的一级指针(即一维数组),通过地址转换 来模拟二维数组的行为
代码较简单,略去
三、分配一个长度为m+m*n的二级指针,前m个地址分别存放后m*n个地址中每行的首地址
#include<stdio.h> #include<stdlib.h> #include<string.h> //二维数组内存分配 int main() { int i,j,c=0; // i,j为下标,c为赋初值方便 int m,n; // m行 n列 int **p; int *head; scanf("%d %d",&m,&n); p=(int **)malloc(sizeof(int *)*m+sizeof(int)*m*n); if (p==NULL) { puts("memory allocation error!"); return; } head=(int *)p+m; //指向数据内容起始的首地址,注意地址转换 memset(p,0,sizeof(int *)*m+sizeof(int)*m*n); //内存区域清零 for (i=0;i<m;i++) { //p[i]=head+(i*n); //both is ok *(p+i)=head+(i*n); } for(i=0;i<m;i++) { for (j=0;j<n;j++) { *(*(p+i)+j)=c++; } } for(i=0;i<m;i++) { for (j=0;j<n;j++) { printf("%x: %4d\t",&p[i][j],p[i][j]); } printf("\n"); } free(p); system("pause"); return 0; }
第一种方法需要分配m+1次内存,释放时也要先分别释放一级指针,再释放二级指针;
第三种方法分配连续的(m*n+m)*sizeof(int)个内存空间,操作较快。同时可以用p[i][j]下标方式访问。
内存分配需要用到sizeof(type); 指针加操作时 直接p+1效果为p的地址再加上sizeof(p)个字节。不能画蛇添足为p+sizeof(p)。
关键一:分配内存后必须判断是否分配成功
int *p=(int *)malloc(sizeof (int)*10);
if(p!=NULL)
// operate
关键二:分配内存 使用完成后必须释放,否则会造成内存泄露。***虽然操作系统也会对程序员申请的内存进行回收,但程序员有责任对自己申请的内存释放***。
free(p); // 腾讯上次面试 如何避免内存泄露,自己的回答是 类似写大括号 {}一样,malloc之后直接写上free();中间写自己的代码