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

Posted

技术标签:

【中文标题】一个字符串正在影响 C 上另一个字符串的大小、长度和值【英文标题】:One string is affecting the size, length and value of another one on 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。您必须将字符串传递给这些函数。 【参考方案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 编程时,您必须比使用“更安全”的语言时更加小心和注意语言规则。对于初学者来说,这是一种强硬且不友好的语言。

【讨论】:

以上是关于一个字符串正在影响 C 上另一个字符串的大小、长度和值的主要内容,如果未能解决你的问题,请参考以下文章

C语言字符串常量,字符数组占内存大小问题?

C语言中比较字符串大小的判断标准是啥?

如何获取一个程序的输出并将其用作 C++ 上另一个程序的输入?

C 语言字符串操作 ( strlen 与 sizeof 函数 | 计算 字符串长度 与 内存块大小 )

c语言数组长度函数

c语言中strcmp函数 如果两个字符串长度不一样时要怎么比较大小啊?