【问题标题】:Just curiosity, why does this not cause a seg fault?只是好奇,为什么这不会导致段错误?
【发布时间】:2012-06-01 20:43:50
【问题描述】:

所以我的理解是,一个 C 字符串,例如“0123456789”,实际上会占用一个由 11 个字符组成的数组,其中 10 个字符用于正文,一个用于终止 null。如果这是真的,那么为什么下面的代码不会导致某种错误?

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

int main(int argc, char ** argv){

    char * my_string = "0123456789";
    /* my string should occupy 11 bytes */

    int my_len = strlen(my_string);
    /* however, strlen should only return 10, 
        because it does not count the null byte */

    char * new_string = malloc(my_len);
    /* allocate memory 10 bytes wide */

    memcpy(new_string, my_string, my_len);
    /* copy the first 10 bytes from my_string to new_string
        new_string should NOT be null terminated if my understanding
        is correct? */

    printf("%s\n", new_string);

    /* Since new_stirng is NOT null terminated it seems like this should
        cause some sort of memory exception.
        WHY DOES THIS NOT CAUSE AN ERROR?

    */

    return 0;
}

由于new_string 不是空终止,我希望printf 永远读取,直到它到达一些其他应用程序内存,或者随机放置在某处的0x00 并且崩溃或打印一些奇怪的东西。怎么回事?

【问题讨论】:

  • 你很幸运,0x00 接近字符串。我认为,非常接近,因为在第一次使用之前内存通常是零填充的。
  • @osgx:当发生未定义的行为时,如果一切都发生了,我认为自己很幸运,让我有机会避免它......
  • 如果你想搞砸一切,在 Valgrind 下运行你的程序或用 AddessSanitizer 编译它(包含在 llvm 3.1 中)。未定义意味着任何事情都可能发生,甚至什么都没有。

标签: c char segmentation-fault


【解决方案1】:

您已创建undefined behavior。该行为取决于编译器和平台。它可能会崩溃。它可以工作。它可以让你敬酒。它可能会将您的计算机坍塌成一个奇点并吸收太阳系。

在您的情况下,new_string[11] 处的内存可能已经是 0,即'\0',或终止空字符。

【讨论】:

  • 但是另一个(不是 ANSI-C)标准不是禁止重力坍缩吗?例如通过一些物理定律?
【解决方案2】:

因为它是未定义的行为。未定义的行为并不意味着段错误,尽管这是一种可能性。

【讨论】:

    【解决方案3】:

    在您的情况下,您从 malloc 获得的特定内存块以前从未使用过(由您的程序),并且它可能在分配时被操作系统零初始化。因此,第 11 个字节可能为零,因此没有错误。在运行时间较长的程序中,malloc 可能会返回第 11 个字节不为 0 的脏内存块,因此您将在 printf 语句中遇到问题。在实践中,您要么打印垃圾(直到遇到第一个 null),要么打印段错误(如果在分配区域结束之前没有 null)。

    (正如其他人所说,该行为在形式上是未定义的,我只是在解释您所看到的)。

    【讨论】:

      【解决方案4】:

      或随机放置的 0x00 某处......打印一些奇怪的东西。

      这是常见的行为。实际会发生什么是不确定的。

      【讨论】:

        【解决方案5】:

        这是未定义的行为。在某些情况下,它可能会导致崩溃,这取决于我想象的内存布局

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-03-16
          • 2017-08-18
          • 2016-09-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多