动态二维数组似乎分配了更多的内存

时间:2013-11-14 22:13:11

标签: c arrays

我正在尝试使用以下代码在C中分配动态二维数组:

int **allocateMatrix(int rows, int columns) {

    int i = 0;
    int **p = NULL;

    p = (int**) calloc(rows, sizeof(int*));
    for(; i < rows; i++) {

        p[i] = (int*) calloc(columns, sizeof(int));
    }

    return p;
}

代码有效但实际上它正在分配所需内存的两倍。

例如,如果我传递参数rows = 2columns = 3,我会得到一个2行乘8列的数组。

我做错了吗?

谢谢。

修改

矩阵的内容(从文件加载)是:

-1 5 0
4 0 2

这就是在分配和赋值之后内存的样子:

Memory

4 个答案:

答案 0 :(得分:3)

它正在分配正确的内存量,但它分配的内存比简单的2D数组要多,因为您创建的内容不是简单的2D数组。

假设有32位系统(sizeof(int) == sizeof(int *)sizeof(int) == 4),那么:

  • 一个简单的2D数组需要2 x 3个整数= 6 x 4 = 24个字节
  • 动态2D数组需要2个指针加2 x 3个整数= 8 x 4 = 32个字节

那是在内存分配开销的任何因素之前。所以不是两次,而是更多。

您正在做的事情的优点是您可以撰写p[i][j]并获得正确的结果。如果您模拟了一个简单的2D数组,则必须自己进行下标计算:p[i*3+j]或使用(*p)[i][j],具体取决于您如何定义指针p

答案 1 :(得分:1)

AFAICT,你有20个元素的数组截图是因为..你告诉Netbeans(用@20)从内存位置(**(matrix))开始显示20个元素。当你把它改成'@ 3'时会发生什么?

但是,基于此评论:

  

实际上它不仅仅是双倍。我知道,因为当我尝试分配值时,它们在内存中不是连续的,但是它们被移位(我可以在netbeans的调试窗口中看到它)。

当您分配内存时,您正在调用一个库,该库可以确定如何从操作系统请求它可以使用的空间,然后是操作系统给出的尚未使用的空间。< / p>

您正在假设分配器的工作方式可能正确也可能不正确。它可以以您不期望的方式有效地分配空间,尤其是由于虚拟分页机制。简而言之,对分配器的连续调用并不保证分配连续的内存,而且很少会这样。

如果你想为一个双数组样式结构使用一个指针数组,并且绝对必须以更“预期”的方式拥有连续的地址,你可以试试这个:

int **allocateMatrix(int rows, int columns) {

    int i = 0;
    int **p = NULL;
    int *d = NULL;


    p = (int**) calloc(rows, sizeof(int*));
    d = (int*) calloc(rows * columns, sizeof(int));

    for(; i < rows; i++) {
        p[i] = d + i * columns;
    }

    return p;
}

(代码未经测试)

答案 2 :(得分:0)

这不是因为它有一个二维数组大小(rows * columns * sizeof(int *))来存储指针和一个二维数组空间来存储实际值(rows * columns * sizeof(int))?

答案 3 :(得分:0)

您可以使用以下方法(不需要额外的内存来存储数据,实际上是内存中的1D连续数组):

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

int (*allocateMatrix(int rows, int columns))[]{
    int (*p)[columns] = calloc(rows, columns * sizeof(int)),
        i, j;
    for (i = 0; i < rows; i++) {
      for (j = 0; j < columns; j++) {
        p[i][j] = rows*i + j;
      }
    }
    return p;
}


int main(int argc, char *argv[]) {
  int rows = 4, cols = 5,
     (*array)[cols] = allocateMatrix(rows,cols);

  int i, j;
  for (i = 0; i < rows; i++) {
    for (j = 0; j < cols; j++) {
      printf("array[%d][%d] = %2d\n", i, j, array[i][j]);
    }
  }
  free(array);
  return 0;
}

输出:

array[0][0] =  0
array[0][1] =  1
array[0][2] =  2
array[0][3] =  3
array[0][4] =  4
array[1][0] =  4
array[1][1] =  5
array[1][2] =  6
array[1][3] =  7
array[1][4] =  8
array[2][0] =  8
array[2][1] =  9
array[2][2] = 10
array[2][3] = 11
array[2][4] = 12
array[3][0] = 12
array[3][1] = 13
array[3][2] = 14
array[3][3] = 15
array[3][4] = 16