【问题标题】:What is the value of an uninitialized string in c? [duplicate]c中未初始化的字符串的值是多少? [复制]
【发布时间】:2013-02-05 07:45:26
【问题描述】:

可能重复:
initial value of int array in C

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

int main(){
    char name[10];
    printf("%s\n", name);
    return 0;
}

C 中未初始化的字符串持有什么值?编译器是否会自动分配大小为 10 的存储空间并用垃圾值填充它?写上面的代码基本上会发生什么?

【问题讨论】:

  • @Yuushi 这个链接真的很有帮助。但是 C 字符串和 C int 数组之间是否存在直接对应关系?我们是否也可以将字符串的所有字符初始化为特定值,例如: char name[10] = {'a'} ; ?(我们可以对 C int 数组执行此操作,如您指出的问题的第二个答案中所写)。
  • intchar数组的初始化是不同的,是的,你不能写char c[10] = {'a'}来初始化一个char数组与所有a的(你也不能这样做int x[10] = {1} 来初始化一个全为 1 的 int 数组)。但是,这不是您的问题。所述问题完全相同,答案完全相同,无论类型如何。
  • @Nikunj Banka 不,您不能以这种方式启动字符数组char name[10] = {'a'}。仅当您想像这样char name[10] = {0} 以 0 启动时,才可以这样做
  • @Yuushi,charint的初始化有什么不同? char 只是 C 语言中的一种整数类型。
  • “未初始化的字符串”听起来无效。你怎么能确定一个序列以 '\0' 结尾而不把 '\0' 放在那里? @MohamedKALLEL char name[10] = {'a'}; 是一个有效的初始化。它将第一个字节设置为“a”,接下来的九个字节设置为 0。

标签: c


【解决方案1】:

在堆栈上分配了 10 个字节,仅此而已。它们的值保持原样,这意味着它是在分配之前写入这 10 个字节的值。

【讨论】:

  • 这 10 个字节包含什么值?如果什么都没有定义,那么我说分配垃圾值是正确的吗?
  • @NikunjBanka 是的,这是正确的。虽然他们没有被主动分配。 :-)
  • @NikunjBanka:未执行任何分配。
【解决方案2】:

由于字符串未初始化,因此未定义值 - 它可以是任何值。我还要说打印未初始化的字符串是不安全的,因为它没有终止零字符,所以理论上你最终可能会打印超过 10 个字符。

还有一件事——C 不会用任何东西填满存储空间。它只是保持原样。

编辑:请注意,我并不是说只要您有一个 0 终止字符,就可以安全地访问未初始化的字符串。调用未定义的行为从来都不是安全的,因为它是未定义 - 你永远不知道会发生什么。

【讨论】:

  • +1 表示“它可能会打印超过 10 个字符”。另外,您说它不会填写任何内容。但是如果我将字符串声明为静态呢?我认为编译器只有在声明为自动时才不会填写任何内容。如果我错了,请纠正我。
  • 因此,这个答案非常接近于不正确/误导。即使这 10 个字节中有一个终止 0,它仍然会调用未定义的行为来访问未初始化的变量(c 字符串不同)。
  • @KingsIndian 我只是说你不能确定只会打印 10 个字符,从来没有说过如果有一个终止 0 字符就可以使用变量。
  • IMO,它给人的印象是,如果分配的内存(10 个字节)中有一个终止 0,则可以打印/访问它,这是错误的。
  • @KingsIndian 添加了一个编辑来解决您的问题。
【解决方案3】:

未初始化变量的内容是 - 除了例如在 Java 中 - 未定义。换句话说:内容由最近压入堆栈以供其他方法调用的值组成。

【讨论】:

    【解决方案4】:

    在您的特定示例中,它可能会为零。不过没关系。

    关键是它未定义。如果你不能相信它总是一样的,它对你没有用。你不能做任何假设。您的代码的任何其他部分都不能依赖它。就好像它不存在一样。

    如果您对实际内容的来源感到好奇,它们是存储在堆栈中的先前执行上下文的剩余部分。如果你运行几个函数调用,你会留下垃圾,你的程序可以随意覆盖。那些只适合覆盖的字节可能会出现在您的字符串中。

    【讨论】:

    • "在您的特定示例中,它可能为零。" 我对此表示怀疑。请解释一下。
    【解决方案5】:

    C 标准使用术语“未指定”,即。 e.它可以是任何东西。在现实生活中,它很可能会充满随机垃圾,如果你不走运,它不会有终止零字节,所以你调用 undefined behavior 并且可能调用@987654321 @ 将崩溃(分段错误,有人吗?)。

    【讨论】:

    • 所以这意味着不同的编译器可以决定不同的值,但这不会是可移植的?
    • @Noor 这一点也不便携。它甚至可以从程序的一次运行到另一次运行有所不同。真的,期望对未定义的行为和未指定的值进行合理解释是没有意义的。
    【解决方案6】:

    它包含垃圾(随机)值。请务必查看有关存储类的更多信息以更好地理解。

    【讨论】:

      猜你喜欢
      • 2023-01-03
      • 2012-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多