【问题标题】:Printing a malloc() declared array - A very short code that prints out of bounds?打印 malloc() 声明的数组 - 打印超出范围的非常短的代码?
【发布时间】:2014-08-09 05:56:10
【问题描述】:

为什么我的程序会打印一个额外的元素,看起来像一个内存位置?

代码:

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

int main()
{
    int i;
    int *n=(int *)malloc(sizeof(int));
    n[0]=1;
    n[1]=2;
    n[2]=3;
    for(i=0;n[i];i++)
        printf("\n%d\n",n[i]);
}

输出:

1

2

3

135153

即使我替换(在主块的第 2 行)

int *n=(int *)malloc(sizeof(int));

int *n=(int *)malloc(sizeof(int)*3);

输出是一样的。我在这里错过了什么?

编辑:好的,所以据我所知,当你运行一个字符串而不是任何数组时,你只能有这样的条件,因为使用 malloc() 分配的数组不会有一个终止字符,如 \0。

【问题讨论】:

  • 因为你很幸运,这是未定义的行为。 for 循环中的条件导致越界。
  • 所以当 malloc() 时你不能像这样检查 n[i] 吗?
  • @user3833914 不,你不能,因为你不知道n[i] 值之后的内存是什么。
  • n[i] 是一个值,如果值等于 0,则循环条件无效,否则循环停止(即,如果 n[i] != 0)循环继续。在您的情况下,您很幸运没有崩溃。
  • @WhozCraig 我也坚信这一点。 “幸运”显然是一个善意的讽刺:)

标签: c arrays malloc printf bounds


【解决方案1】:

你显然需要分配sizeof(int)*3,否则你会覆盖一些其他的内存。在这里,这不起作用,因为您的简单应用程序在堆上没有其他内容。

另一个问题是 for 循环中的结束条件。 n[i] 表示直到数组中偶然出现 0。您的数组不是以 0 结尾的,因此它会打印垃圾。请改用for (i=0;i&lt;3;i++)

【讨论】:

    【解决方案2】:

    您的两个版本的代码都显示undefined behaviour,因此输出可能相同或不同,或者可能崩溃或其他原因。

    如果您尝试访问超出成功分配的内存,您可能会得到任何奇怪的输出。

    int *n=(int *)malloc(sizeof(int));
    if(n != NULL)
    {
      n[0]=1;
      n[1]=2;  /* UB 1 */
      n[2]=3;  /* UB 2 */
      for(i=0;n[i];i++) /* UB 3 */
        printf("\n%d\n",n[i]); /* UB 4 */
    }
    

    根据您建议的更改,仅修复了 UB1 和 UB2。 UB3 和 UB4 仍未定义。

    【讨论】:

      【解决方案3】:

      这与你的 for 循环有关: 将其替换为:for(i=0;i &lt; 3;i++)

      【讨论】:

        猜你喜欢
        • 2015-07-09
        • 1970-01-01
        • 2018-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多