差异 b/w 将内存分配给 1 行或逐行的 2D 数组 [英] difference b/w allocating memory to 2D array in 1 go or row by row

查看:14
本文介绍了差异 b/w 将内存分配给 1 行或逐行的 2D 数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于这两种情况,访问数组或内存分配会有什么影响:

what would be the impact in accessing of array or in memory allocation for these two cases:

1.

    int **arr;
    arr = malloc( sizeof(int) * row * column );

2.

    int **arr;
    arr = malloc( sizeof(*arr) * row);
    for(i=0; i<row; i++)
        arr[i] = malloc( sizeof( **arr) * column));

推荐答案

  • 首先,影响"是你的第一种方法被破坏了.它不会通过 int ** 指针工作.

    为了像您尝试在第一种方法中那样一次性分配一个二维数组,您实际上必须分配一个足够大的一维数组

    In order to allocate a 2D array in one shot as you are trying to do it in your first method, you actually have to allocate a 1D array of sufficient size

    int *arr = malloc( row * column * sizeof *arr );
    // Note: `int *`, not `int **`
    

    并通过手动索引重新计算来执行访问,例如而不是做 arr[i][j] 你必须做 arr[i * column + j].

    and perform access by manual index re-calculation, e.g. instead of doing arr[i][j] you have to do arr[i * column + j].

    尝试将分配的指针存储在 int **arr 中,然后以 arr[i][j] 访问您的数组只会导致崩溃.

    Trying to store the allocated pointer in int **arr and then access your array as arr[i][j] will simply lead to crashes.

    其次,你的第二种方法是可以的.只是在第二种方法中,您实际上并不需要通过多个独立的 malloc 调用来分配二级内存.一次可以分配整个二级内存

    Secondly, your second method is OK. It is just that in the second method your are not really required to allocate the second-level memory by multiple independent malloc calls. You can allocate the whole second-level memory in one shot

    int **arr = malloc( row  * sizeof *arr );
    int *arr_data = malloc( row * column * sizeof *arr_data );
    

    然后在行之间分配预先分配的二级内存

    and then just distribute that pre-allocated second-level memory between the rows

    for (i = 0; i < row; i++)
      arr[i] = arr_data + i * column;
    

    (当然,如果您愿意,您可以独立分配行.它也可以工作.我想一次性分配它们的原因是为了更好地说明第一种方法和第二种方法之间的相似性,正如评论的那样下面.)

    (Of course, you can allocate the rows independently, if you wish so. It will also work. The reason I wanted to allocate them in one shot is to better illustrate the similarity between the first and the second approach, as commented below.)

    现在,通过查看这两种方法,您可以很容易地看到它们本质上都在做同样的事情.唯一的区别是,在第一种方法中,您通过每次计算 arr + i * column 即时找到行的开头(注意 arr[i * column + j] 等价于 (arr + i * column)[j]).在第二种方法中,您使用相同的 arr_data + i * column 公式预先计算所有行的开头,并将它们存储在单独的行索引"数组中以供进一步使用 arr.

    Now, by looking at these two methods you can easily see that both of them essentially do the same thing. The only difference is that in the first method you find the beginning of the row on-the-fly by calculating arr + i * column every time (note that arr[i * column + j] is equivalent to (arr + i * column)[j]). In the second method you pre-calculate all row beginnings in advance by using the same arr_data + i * column formula, and store them for further usage in a separate "row index" array arr.

    因此,它基本上归结为内存使用(第一种方法需要较少的内存)和速度(第二种方法可能更快,但不一定更快)之间的权衡.同时,第二种方法支持二维数组访问的自然"语法 - arr[i][j],而在第一种方法中,您必须使用更复杂的一维访问语法和索引重新计算.

    So, it basically boils down to trade-off between memory usage (first method requires less memory) and speed (the second method is potentially, but not necessarily, faster). At the same time the second method supports the "natural" syntax for 2D array access - arr[i][j], while in the first method you have to use more convoluted 1D access syntax with index recalculation.

    这篇关于差异 b/w 将内存分配给 1 行或逐行的 2D 数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆