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();中间写自己的代码