首页 > 代码库 > C语言动态分配二维数组内存

C语言动态分配二维数组内存

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;
}
View Code

 

二、分配一个长度为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();中间写自己的代码