【问题标题】:C memory questionC 内存问题
【发布时间】:2011-08-22 16:38:46
【问题描述】:
char buffer[10];
strcat(buffer, "hi");
printf("%s", buffer);

在上面的代码中,它打印了一些奇怪的符号或数字,后跟“hi”,我知道 strcat 正在附加到缓冲区。我通常将缓冲区中的内存归零。但我很好奇为什么我通常必须这样做。

如果我在没有 strcat 的情况下执行 printf("%i", buffer);,它只会打印一个随机数。那个号码是多少?在我用任何东西填充缓冲区之前,任何人都可以解释或链接到解释缓冲区中的内容的 tut 吗?

【问题讨论】:

  • 该随机数是您创建它时碰巧驻留在内存中字符缓冲区位置的任意垃圾。

标签: c windows memory strcat


【解决方案1】:

“缓冲区”是堆栈上的一个 10 字节区域,它包含最后写入该内存区域的任何内容。当您使用 strcat 时,它会在该区域中的第一个空字节之后连接“hi”(因此,如果第一个空字节超过 10 个字节,您将覆盖堆栈上的某些内容)。当您在不归零的情况下打印时,它会打印字节,直到第一个 0(空)。同样,这可能会打印超过 10 个字节。

当您 printf (%I, buffer) 时,您会打印该位置的地址。

【讨论】:

    【解决方案2】:

    首先,您需要对缓冲区进行零初始化:

    char buffer[10] = {0};
    buffer[0] = 0; /* As R.. points out, initializing all elements is excessive. */
    

    其次,数字为buffer的地址,为十进制。如果你真的想打印,你最好打印:

    printf("%p\n", buffer);
    

    【讨论】:

    • 这种类型的初始化在 C 中不起作用,只有 C++ AFAIK
    • @hexa 再次检查 :-) 它在 C89 和之后的所有内容中都有效。
    • {0} 可以对 任何类型 进行零初始化,但在这里它等同于使用 "",而且我认为后者可能不会让大多数读者感到困惑。 .
    • 另请注意,无论是哪种方式,它都会用零初始化 整个 数组。对于可能不需要/浪费时间的大缓冲区。因此,通常最好让数组保持未初始化状态,并在初始化后简单地写入 buffer[0]=0;
    • @R.. 没有考虑性能影响,这很明智:-)
    【解决方案3】:

    您需要一个终止符 '\0' 来标记字符串的结尾, 使用

    strcpy(buffer,"hi");
    

    strcat() 尝试附加到假定为 '\0' 终止的现有字符串。您的缓冲区未初始化。

    【讨论】:

      【解决方案4】:

      在追加之前先执行memset(buffer, 0, 10) 将内存归零。

      【讨论】:

        【解决方案5】:

        strcat() 函数将 src 字符串附加到 dest 字符串,覆盖 dest 末尾的空字节 ('\0'), 然后添加一个终止空字节。字符串可能不会 重叠,并且目标字符串必须有足够的空间用于 结果。

        buffer 不是 '\0' 终止的,因为它没有初始化,我们不知道它包含什么。因此,这是一种未定义的行为。您应该首先确保缓冲区是 '\0' 终止的。

        而且打印出来的数字不是随机数而是缓冲区的起始地址。

        【讨论】:

          猜你喜欢
          • 2010-11-05
          • 1970-01-01
          • 2010-10-14
          • 2011-07-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多