为啥在 C 中使用错误的格式说明符会使我的程序在 Windows 7 上崩溃?

Posted

技术标签:

【中文标题】为啥在 C 中使用错误的格式说明符会使我的程序在 Windows 7 上崩溃?【英文标题】:Why does using the wrong format specifier in C crash my program on Windows 7?为什么在 C 中使用错误的格式说明符会使我的程序在 Windows 7 上崩溃? 【发布时间】:2011-05-13 00:37:32 【问题描述】:

我的程序如下;

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

int main()

        char string[] = "Gentlemen start your engines!";
        printf("That string is %s characters long.\r\n", strlen(string));
        return 0;

我在 gcc 下编译,虽然它没有给我任何错误,但每次我运行它时程序都会崩溃。从我看过的例子来看,代码似乎很好。很高兴知道我是否做错了什么。

谢谢。

【问题讨论】:

谢谢大家。应该已经看到了,我刚开始使用 C 并且到目前为止只使用字符串来玩文本程序,所以 %s 只是自动浮现在脑海中。 +1 因为我知道我应该一直使用 %zu 而不仅仅是 %u 甚至 %d 如果您使用的是 GCC,请使用-Wall-Wextra-Werror 来加速您的错误。 GCC 能够检查格式字符串并警告 printf-、scanf-、strftime- 和 strfmon 类函数的参数不正确。 【参考方案1】:
 printf("That string is %d characters long.\r\n", strlen(string));

改为:

 printf("That string is %s characters long.\r\n", strlen(string));

【讨论】:

还有一件事,将变量名“string”更改为其他名称。 “字符串”是保留字。 好的,谢谢。我使用“字符串”来组合一个具有字符串长度的快速程序,因为我正在编写一个检测回文的程序并想了解我将如何做。不过我会记住以后不要使用它。 在语法上,string 不是关键字。但是,正如所有以strmemwcs 开头的名称一样,“保留供将来使用”作为&lt;string.h&gt; 标头中的字符串函数。 (来源:ISO C99, 7.26.11)【参考方案2】:

printf() 中使用不正确的格式说明符会调用未定义行为。正确的格式说明符应该是%zu(不是%d)因为strlen()的返回类型是size_t

注意:%zu中的长度修饰符z表示长度与size_t相同的整数

【讨论】:

Windows 上的 gcc 何时停止使用 Microsoft CRT?我上次在 MinGW 上使用 %zu 时出错了,还是有另一个使用 glib 的 gcc 版本? @Pete:你不应该得到任何这样的错误。确保您使用的是支持 C99 的最新版 MinGW。 甜蜜! MingW 的任何 ETA 在 Windows _wfopen 等函数之上实现模拟 UTF-8 语言环境?【参考方案3】:

你有错误的格式说明符。 %s 用于字符串,但您传递的是 size_t (strlen(string))。在printf() 中使用不正确的格式说明符会调用未定义的行为。 请改用%zu,因为strlen() 的返回类型是size_t

所以改变

 printf("That string is %s characters long.\r\n", strlen(string));

到:

 printf("That string is %zu characters long.\r\n", strlen(string));

由于您使用的是gcc,请查看here 了解更多信息,可以将什么传递给printf

【讨论】:

使用gcc进行编译并不一定意味着你使用glibc来执行你的代码。【参考方案4】:

你这里有问题 printf("That string is %s characters long.\r\n", strlen(string));

printf("That string is %d characters long.\r\n", strlen(string)); %d 因为你想打印 str 的长度(strlen 返回数字)

【讨论】:

【参考方案5】:

程序崩溃,因为格式化例程尝试访问地址为0x0000001D 的字符串,这是strlen() 的结果,其中与字符串完全不同,可能根本没有可访问的内存。

【讨论】:

以上是关于为啥在 C 中使用错误的格式说明符会使我的程序在 Windows 7 上崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 unwind segue 会使我的应用程序崩溃?

从 .dae 加载顶点会使我的程序变慢,为啥?

为啥 ntdll.dll 会使我的 c++ 可执行文件崩溃?

为啥大型本地数组会使我的程序崩溃,而全局数组却不会? [复制]

为啥 __inbyte 会使我的软件崩溃?

为啥在使用 FBO 进行多重采样时,OpenGL 会使我的场景变亮?