出于某种原因,在多年未使用 C 编程归来后,我无法完成这项工作:
(这编译没有提示,但它导致崩溃,当我删除可执行文件运行正常的 strcat 行)
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv){
char clibdir[50] = "C:\\Users\\______000\\Desktop\\nodeC\\libraries\\c";
char varsfile[20] = "\\variables.xml";
printf("%s\n", clibdir); //ok
printf("%s\n", varsfile); //ok
char *varspath = strcat(clibdir, varsfile); //this is provoking a crash
printf("%s\n", clibdir); //prints right before crash
printf("%s\n", varspath); //prints right before crash
return 0;
}
这打印得非常完美,但它让我的 exe 崩溃了。这是我的命令行(我使用的是 Visual Studio 2010 中的 cl.exe):
"%vcbin%\vcvars32.bat" && "%vcbin%\cl.exe" /nologo /EHsc main.cpp /link /subsystem:console
您的代码正在崩溃,因为您没有在 clibdir
中分配足够的空间来保存初始字符串和附加字符串,因此出现缓冲区溢出。问题是,您已经破坏了 main()
函数的返回堆栈,因此当您从 main()
程序返回时,程序变得困惑并崩溃。您可能会发现,如果将 return 0;
替换为 exit(0);
,您的程序将不再崩溃。这是巧合 - 不是推荐的修复方法。
故事的寓意是“确保有足够的空间容纳您附加的字符串”!
明智的解决方法是将 clibdir
的大小从 50 增加到至少 60。
...还有...当您提出问题时,请确保您在问题中显示的代码与您在计算机上运行的代码一样会崩溃。问题的原始版本有:
char clibdir[50] = "\\libraries\\c";
代替:
char clibdir[50] = "C:\\Users\\______000\\Desktop\\nodeC\\libraries\\c";
而且没有人能理解为什么代码会崩溃——因为,事实上,原始代码不应该崩溃。
我是一名优秀的程序员,十分优秀!