【问题标题】:One string is affecting the size, length and value of another one on C一个字符串正在影响 C 上另一个字符串的大小、长度和值
【发布时间】:2022-01-23 04:49:35
【问题描述】:
int main ()
{
    /*
    char a[] = "abc";
    printf("strlen(a): %li", strlen(a));
    printf("\nsizeof(a): %li", sizeof(a));
    */

    char b[3];
    printf("\nstrlen(b): %li", strlen(b));
    printf("\nsizeof(b): %li", sizeof(b));

    printf("\nb = ");
    puts(b);

return 0;
}

当我运行上面的代码时,它会输出以下内容:

strlen(b): 1

sizeof(b): 3

b =

但如果我撤消评论,它会输出:

strlen(a): 3

sizeof(a): 4

strlen(b): 6

sizeof(b): 3

b = ����abc

为什么会发生这种情况?我希望能对它进行深入的解释,如果可能的话,可以快速“修复”它,这样我就不会再遇到这个问题了。

总的来说,我是编程和 C 的初学者,根据我到目前为止所学的知识,这不应该发生

感谢和抱歉,如果我违反了本网站的任何规则,我也是新来的!

【问题讨论】:

  • 程序有未定义的行为,因为数组 b 未初始化。
  • 由于b 不包含字符串,因此不允许将其传递给strlen。也不允许将其传递给puts。您必须将字符串传递给这些函数。

标签: arrays c string char


【解决方案1】:

strlen(b) 导致undefined behavior 因为数组b 未初始化。因此数组的内容是不确定的。 strlen 如果数组的垃圾内容中碰巧有一个空字节(充当空终止符),则可能返回一个小数字,如果数组中没有空字节但内存中有一个空字节,则可能返回一个大数字与它相邻(访问时碰巧不会崩溃),或者它可能会出现段错误,或者以其他不可预知的方式失败。您观察到的特定不当行为很容易取决于附近其他内存的内容,因此会受到添加或删除其他变量或以明显不相关的方式更改周围代码的影响。

puts(b) 是类似的未定义行为。

(另一个错误:sizeofstrlen 都返回 size_t,其正确的 printf 格式说明符是 %zu,而不是 %li,后者将用于 long int。)

我希望能对它进行深入的解释,如果可能的话,我会快速“修复”它,这样我就不会再遇到这个问题了。

不要试图读取或使用尚未初始化的局部变量的内容。

另请参阅 What happens to a declared, uninitialized variable in C? Does it have a value?(Why) is using an uninitialized variable undefined behavior?

如果您启用编译器警告,您的编译器可以警告您有关此情况的某些实例,例如gcc catches this example。 valgrind 等工具也可以提供帮助。

总的来说,我是编程和 C 的初学者,根据我到目前为止所学的知识,这不应该发生

相反,这种行为在 C 中非常普遍。C 语言不保证对此类错误进行任何检查,并且实现通常不提供它们。你应该习惯这种语言不会阻止你做错误的事情的可能性,而是会以不可预测的方式行为不端(或者更糟糕的是,在一段时间内似乎可以正常工作)。因此,在使用 C 编程时,您必须比使用“更安全”的语言时更加小心和注意语言规则。对于初学者来说,这是一种强硬且不友好的语言。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-12
    • 1970-01-01
    • 2017-07-27
    • 2015-06-18
    相关资源
    最近更新 更多