使用memset在C中初始化2d数组

时间:2018-05-26 17:35:25

标签: c arrays

在使用memset初始化二维数组后打印二维数组时出现异常。如果我初始化每个元素然后访问它,那么就没有错误。 请帮助找出代码中的错误。

#include "stdafx.h"
#include "stdlib.h"
int r = 0;
int c = 0;
int **twoDArray() {

    int *arr[5];

    for (r = 0; r < 5; r++) {

        arr[r] = (int*)malloc(2 * sizeof(int));

    }
   // 
    for (r = 0; r < 5; r++) {
        for (c = 0; c < 2; c++) {
            arr[r][c] = 1;
            printf("%d \n", arr[r][c]);
        }
    }
    memset(arr, 0, 2 * 5 * sizeof(arr[0][0]));
    for (r = 0; r < 5; r++) {
        for (c = 0; c < 2; c++) {
            printf("%d \n", arr[r][c]); //getting exception here.
        }
    }
    return arr;

}


int main()
{
    int **arr;
    arr = twoDArray();
    for (r = 0; r < 5; r++) {
        for (c = 0; c < 2; c++) {
            arr[r][c] = 0;
            printf("%d \n", arr[r][c]);
        }
    }
    return 0;
}

2 个答案:

答案 0 :(得分:4)

您没有2D阵列。你有一维指向一维数组的指针数组;这些数组中的每一个都可以(并且99.9%可能是)存储器中的不同地址。因此,您不能将它们视为一个连续的块,如memset所做的那样。

最好的(也是最适合缓存的)选项是动态分配整个数组:

int *arr = malloc(2 * 5 * sizeof(int));

这将要求您进行手动索引:

for (r = 0; r < 5; r++) {
    for (c = 0; c < 2; c++) {
        arr[r * 2 + c] = 1;
        printf("%d \n", arr[r * 2 + c]);
    }
}

如果你知道编译时的数组大小(如果25是实际常量),你也可以使arr指向一个实际的数组,允许语法2D索引:

typedef int Array[2];

Array *arr = malloc(5 * sizeof(Array));

for (r = 0; r < 5; r++) {
    for (c = 0; c < 2; c++) {
        arr[r][c] = 1;
        printf("%d \n", arr[r][c]);
    }
}

请注意,在原始代码中,还有一个问题是您将指针返回到arr,这是一个局部变量,使指针立即悬空。

答案 1 :(得分:3)

这是一个指针数组。你可以肯定两件事

  • arr[0]arr[4]是连续的。
  • 分配的块是连续的。

但是谁告诉你每个指针指向的每个malloc分配的内存块也是连续的?没有人这样做。你认为它错了。

你的情况 肯定并非如此。这就是为什么你通过访问超出范围的内存来调用未定义的行为。 (在memset)。

这样做 - 它会起作用

int (*arr)[2];
arr = malloc(sizeof *arr * 5);
// do memset - it's fine.

不要转换malloc的返回值。这是多余的。

在早先的案例中有类似的事情: -

                                  +-------------+
        +-------+         +------>+  arr[0][0]  |
arr[0]  |       |         |       |      |    arr[0][1]
        |   +-------------+       +------+------+
        +-------+
        |       |     +------+------+
arr[1]  |    +------->+      |      |
        +-------+     |      |      |
        |       |     +-------------+              +------+------+
arr[2]  |    +-------------------------------------+      |      |
        +-------+                                  |      |      |
        |     | |                 +------+------+  +------+------+
arr[3]  |     +------------------>+      |      |
        +-------+                 |      |      |
        |       |                 +------+------+
arr[4]  |    +  |
        +-------+
             |                        +------+------+
             +----------------------->+      |      |
                                      |      |      |
                                      +------+------+