现在的位置: 首页 > 综合 > 正文

动态分配二维数组 连续内存,不连续内存实现

2013年03月29日 ⁄ 综合 ⁄ 共 1909字 ⁄ 字号 评论关闭

方法一:内存不连续

假设数组元素的数据类型是int型,则动态分配二维数组的一般方法是这样:

    int **p = NULL; 

    p = (int **)malloc(nWidth * sizeof(int *));

if (!p)

        return NULL;

    for (int j = 0; j < nWidth; j++)

    {

        p[j] = (int*)malloc(nHeight * sizeof(int))

        if (!p[j])

            return NULL;

    }

这段代码浅显易懂,先分配第1维,在循环分配第2维。假设二维数组是3×2的,每一句运行完后的内存情况如图所示(方格表示内存,xx表示随机数,方格下方是内存地址。当然,地址只是示意而已,与真实情况并不相符)

第一句完后分配了3个内存单元

循环分配后,注意下面3段内存通常是不连续的。这样用下表p[n][m]操作数组没问题,如果整块内存操作就会有问题了,比如下面这句:

原意是想把下面的36个内存单元清0,可是事与愿违,把从p开始后面6个内存单元清0了,p[]不能用了。p后面只有3个已分配的内存单元,却要操作6个,另外3个是未知区域。清了后面虚线的3块未知区域,这就很危险了,可能导致程序崩溃。

这样分配的内存需要循环释放。代码如下:

    for (int j = 0; j < nWidth; j++)

    {

        free(p[j]);

        p[j] = NULL;

    }

    free(p);

    p = NULL;

方法二:内存连续

若要动态分配内存连续的二维数组,那么可以采用如下方法:

    //p是一个指向指针的指针

    int **p = NULL;

    //请求系统分配一个包含nWidthint*指针的空间,p指向空间的首地址。

    //此空间用来作为二维数组的索引

    p = (int **)malloc(nWidth * sizeof(int *));

    if (!p)//malloc失败

        return NULL;

    //请求系统分配一个包含nWidth*nHeightint指针的空间,p[0]指向空间的首地址。

    //此空间用来保存二维数组的数据

    p[0] = (int *)malloc(nHeight * nWidth * sizeof(int));

    if (!p[0])//malloc失败

    {

        free(p);

        return NULL;

    }

    //索引与相应数据的关联

    for(int i = 1; i < nWidth; i++)

        p[i] = p[i-1] + nHeight;//留意并思考此处为什么是直接加上nHeight的值

    memset(p[0], 0, nHeight * nWidth*sizeof(int));//二维数组清零

这段代码解决了分配的空间不连续的问题。每一句运行完后的内存情况如图所示:

第一句和上面一样。

6个内存单元是一次分配的,所以连续。

这个二维数组的数据首地址是p[0],p是第2维的索引首地址。所以如果要对二维数组进行整体的内存(缓冲区 buffer)操作,要以p[0]为操作对象的首地址。

到此,索引与对应的数据地址关联上了。这个二维数组既可以通过下表p[][]来操作,又可以操作缓冲区。操作缓冲区的函数比如memcpycfilewritehugereadhuge使用起来很方便,省去了2次循环的麻烦。

至于释放,不必循环释放。因为malloc了2次,所以只需free两次就行了:

    free(p[0]);     //释放二维数组

    p[0] = NULL;

    free(p);        //释放指针空间

    p = NULL;

参考资料:

http://hi.baidu.com/jiaon/item/52017c5a145debcfd2e10c52

http://hi.baidu.com/_forward001/blog/item/8a7a5f867095c63966096e59.html

http://topic.csdn.net/u/20081124/18/60e5259e-f1ae-4fe9-bda1-cd7b609250d8.html?seed=1045715561&r=60398843#r_60398843

抱歉!评论已关闭.