一个字符串正在影响 C 上另一个字符串的大小、长度和值

One string is affecting the size, length and value of another one on C

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 语言的初学者,根据我到目前为止所学的知识,这不应该发生

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

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

puts(b) 同样是未定义的行为。

(另一个错误:sizeofstrlen 都是 return size_t,正确的 printf 格式说明符是 %zu,不是 %li 而是 long int。)

I would appreciate a good in depth explanation about it principally and if possible a quick "fix" for it so I don't get this problem again.

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

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

如果您启用编译器警告,您的编译器会在某些情况下向您发出警告,例如gcc catches this example。 valgrind 等工具也可以提供帮助。

I'm relatively a beginner in programming and C in general and based on what I learned until now, this shouldn't happen

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