c语言编程如何实现二维动态内存分配

C 语言编程经常需要用到数组,若实现能确定数组的长度,非常好实现数组的定义。但是,如果数组的长度需要经过程序运行后才能确定,动态内存分配就比较合适了。开发时,常用的动态内存分配都是一维的,今天需要用到二维动态内存分配,将过程记录在此。

二维动态内存分配要解决的问题


假设,程序运行过程中,会产生一串数字,长度不固定,需要将这串数字存储下来。

显然,数组非常适合存储这串数字,然而因为长度不能事先确定,所以使用常规的定义数组方法只能定义一个足够大的数组,这往往会造成资源的浪费。动态内存分配非常适合解决事先不能确定长度的数组的定义,动态内存分配很简单,C 标准库提供了 malloc 函数分配内存和 free 函数释放内存。

在上个问题基础上,要求存储 5 串这样的数字。

为了解决这个问题,当然可以用 5 个数组存储,但是如果想将它们连接起来,该怎么做呢?二维数组就非常适合了。上面已经提到,因为每串数字的长度不能确定,较难使用常规的数组定义方法,这就需要二维动态内存分配了

C语言实战


在实现二维动态内存分配前,先来看一维的,假设要存的数字串是字符串。

//  文件名 t.c
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char* buf1 = (char*)malloc(32);     // 分配 32 字节内存
    if(!buf1)
        return -1;

    sprintf(buf1, "this is buf1");
    printf("%s\n", buf1);

    free(buf1);     // 释放内存。
    buf1 = NULL;    

    return 0;
}

buf1 = NULL; 有这句的原因是,释放后,buf1 指针仍然可用,但是其指向的内容已经不可知,为了避免造成未知错误,让其指向 NULL

编译,执行之,结果如下

$ gcc -o t t.c
$ ./t
this is buf1

非常简单。下面解决问题2:

在上个问题基础上,要求存储 5 串这样的数字。

思路是这样的:假设已经分配好 5 个类似于 buf1 的内存,为了将它们连接起来,只要再分配一个长度为 5 的数组,数组单元存储 buf1, buf2, buf3, buf4, buf5 即可。

按照这样的思路,可以按照下面的方法实现:

char* bufs[5];
bufs[0] = buf1;
bufs[1] = buf2;
...

但是,如果要求存 n 串数字串呢,而 n 也事先不能确定呢?这就需要二维动态内存分配了。
代码如下:

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

int main()
{
    typedef char* schar;
    schar* bufs = (schar*)malloc(5*sizeof(schar));
    if(!bufs)
        return -1;

    bufs[0] = (schar)malloc(16);
    bufs[1] = (schar)malloc(17);
    bufs[2] = (schar)malloc(18);
    bufs[3] = (schar)malloc(19);
    bufs[4] = (schar)malloc(15);

    for(int i=0; i<5; i++){
        sprintf(bufs[i], "this is bufs[%d]\n", i);
        printf("%s", bufs[i]);
    }

    for(int i=0; i<5; i++){
        free(bufs[i]);
        bufs[i] = NULL;
    }

    free(bufs);
    bufs = NULL;

    return 0;
}

执行之,得到结果如下

$ gcc -o t t.c
$ ./t
this is bufs[0]
this is bufs[1]
this is bufs[2]
this is bufs[3]
this is bufs[4]

一切符合预期。

阅读更多:   C语言
添加新评论

icon_redface.gificon_idea.gificon_cool.gif2016kuk.gificon_mrgreen.gif2016shuai.gif2016tp.gif2016db.gif2016ch.gificon_razz.gif2016zj.gificon_sad.gificon_cry.gif2016zhh.gificon_question.gif2016jk.gif2016bs.gificon_lol.gif2016qiao.gificon_surprised.gif2016fendou.gif2016ll.gif