【问题标题】:Incorrect 2D array access二维数组访问不正确
【发布时间】:2014-09-03 11:19:47
【问题描述】:

我有一个不寻常的情况。 这是sn-p:

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。

【问题讨论】:

标签: c multidimensional-array malloc


【解决方案1】:

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

s[i] = (short *)malloc(128) 分配 128 个字节。但是随后您尝试将 128 条短裤写入该空间。由于 short 大于 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内存用完后的指针。

【讨论】:

  • 没错。我忘记了 malloc 在我的系统上占用字节数,而 short 是 2 个字节。非常感谢。
【解决方案2】:

首先它不是为二维数组分配内存的正确方法-

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(short) = 2)。

为什么我可以使用s[1][108] 访问s[2][40]?- 因为您访问的数组越界!

怎么样?

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

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

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

尝试像这样分配内存-

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 2012-06-01
    • 2013-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多