2D阵列访问不正确

时间:2014-09-03 11:19:48

标签: c multidimensional-array malloc

我有一个不寻常的情况。 这是片段:

int i, j;
short ** s = (short **)malloc(128);
for(i = 0; i < 14; i++){
    s[i] = (short *)malloc(128);
    for(j = 0; j < 128; j++)
        s[i][j] = 0;
}
printf("Value of s[%d][%d] = %d\n",2,40,s[2][40]);
s[1][108] = 99;
printf("Value of s[%d][%d] = %d\n",2,40,s[2][40]);

我运行时获得的输出是:Value of s[2][40] = 0 Value of s[2][40] = 99

消除循环并写短s [14] [128]产生正确的输出(两个打印中s [2] [40]的值为0)

为什么我能用s [1] [108]访问s [2] [40]? 我在Ubuntu 12.04上使用gcc。

2 个答案:

答案 0 :(得分:6)

您正在访问您分配的空间范围,这会导致未定义的行为。

s[i] = (short *)malloc(128)分配128个字节。但是你试着写128个短裤到那个空间。由于短路大于1个字节,因此您将在分配结束时运行。

此外,short ** s = (short **)malloc(128);可能会分配太多空间,因为您只使用了14行。

假设你想要一个14 x 128的数组:

short **s = malloc( 14 * sizeof *s );
for (size_t i = 0; i < 14; ++i)
    s[i] = malloc( 128 * sizeof *s[i] );

malloc获取字节数,因此您必须将元素数乘以每个元素的大小。

请注意,如果您不需要能够使不同行具有不同大小的功能,那么您可以在一个块中分配它:

short (*s)[128] = malloc( 14 * sizeof *s );

在这两种情况下,您都可以使用s[i][j]

最后,您还应检查malloc返回的指针是否为NULL,并且在完成内存后还检查指针free

答案 1 :(得分:0)

首先,它不是为2D阵列分配内存的正确方法 -

short ** s = (short **)malloc(128); 
for(i = 0; i < 14; i++){
    s[i] = (short *)malloc(128);

这是错误的方式!

 short ** s = (short **)malloc(128); 

这里为short **分配128字节数组的内存。

for(i = 0; i < 14; i++){
    s[i] = (short *)malloc(128);

但您只使用了14 short *。那只是使用了28个字节(因为sizeof(短)= 2)。

为什么我可以使用s[2][40]访问s[1][108]? - 因为您正在访问数组超出范围!

如何?

s[i] = (short *)malloc(128);

这将为每个short *的128字节数组分配内存。这意味着您可以在每个1D阵列中存储最多64个短元素。

但是您正在尝试访问s[1][108] - 表示数组第一行中的第108个元素。它超出了分配的内存范围。所以你不会得到预期的输出。

尝试像这样分配内存 -

short **s = malloc(sizeof(short *) * 14);
for(i = 0; i < 14; i++){
    s[i] = malloc(sizeof(short) * 128);