C字符数组及其长度

标签 c c-strings

我现在正在学习 C 与“C Programming Absolute Beginner's Guide”(第 3 版),其中写道所有字符数组的大小应等于 string length + 1(这是 string -终止零长度)。但是这段代码:

#include <stdio.h>
main()
{
    char name[4] = "Givi";
    printf("%s\n",name);
    return 0;
}

输出 Givi 而不是 Giv。数组大小为 4,在这种情况下它应该输出 Giv,因为 4(字符串长度)+ 1(字符串终止零字符长度)= 5,并且字符数组大小仅为 4

为什么我的代码输出的是 Givi 而不是 Giv

我正在使用 MinGW 4.9.2 SEH 进行编译。

最佳答案

你击中了被认为是 undefined behavior 的东西.它现在正在工作,但由于偶然性,而不是正确性。

在你的情况下,这是因为你的程序中的内存可能在一开始就全部清零了。因此,即使您的字符串未正确终止,它之后的内存恰好为零,因此 printf 知道何时停止。

+-----------------------+
|G|i|v|i|\0|\0|...      |
+-----------------------+
| your  | rest of       |
| stuff | memory (stack)|
+-----------------------+

其他语言(例如 Java)具有针对此类情况的保护措施。然而,像 C 这样的语言,手牵手的事情更少,一方面,它允许更多的灵 active ,但另一方面,给你更多的方式来解决诸如这个这样的微妙问题。换句话说,如果您的代码编译通过,那并不意味着它是正确的,并且它现在、5 分钟或 5 年后都不会崩溃

在现实生活中,几乎从来没有这种情况,您的字符串最终可能会存储在其他东西旁边,而这些东西最终总是会与您的字符串一起打印出来。你永远不会想要这个。像这样的情况可能会导致崩溃、漏洞利用和 secret 信息泄露。

有关示例,请参见下图。想象一下,您正在使用 Web 服务器和字符串“secret”——用户的密码或 key 存储在您的无害字符串旁边:

+-----------------------+
|G|i|v|i|s|e|c|r|e|t    |
+-----------------------+
| your  | rest of       |
| stuff | memory (stack)|
+-----------------------+

每次您输出您认为是“Givi”的内容时,您最终都会打印出 secret 字符串,这不是您想要的。

关于C字符数组及其长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30852420/

相关文章:

c - %d 是什么意思?为什么是 d 而不是另一个字母?

c - 我应该如何清除这些错误,为什么会出现这些错误?

c - 根据长度崩溃对静态数组中的字符串进行排序? |错误分配/访问|

c - 缺少用于 Tcl C 扩展的内置命令 "history"

c - C 中字符串数组和函数的问题

C - 用单个字符替换连续多次出现的字符

C 中 if 语句中的命令无论语句是否为真都会发生

c - 这个 GCC 内联汇编中的参数列表有什么问题?

c - 为什么代码片段 printf 的输出是 ("%. %. %. ");变成%.0 %.0 %.0?

c++ - 在 C++ 项目中链接 Paho C Mqtt 库错误