【发布时间】:2015-03-08 10:53:31
【问题描述】:
由于某些原因,在多年未使用 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
【问题讨论】:
-
它不会导致我崩溃。
-
strcat()将写入clibdir,它使用字符串文字进行初始化。根据编译器选项,clibdir可以转换为指向受保护数据段的指针。在该位置写入会导致未定义的行为。 -
@SleuthEye 不,它被声明为
char[50],它会放在一个可写的位置, -
是的,clibdir 变量大于 50 个字符,导致错误。大小 100 应该没问题。
-
当您不向我们展示实际崩溃的代码时,您希望我们如何调试您的问题?问题的原始版本显示
char clibdir[50] = "\\libraries\\c";,它很短,没有问题。修改后的版本仍然有一个只有 50 个字符长的变量,但它被初始化为 45 个字符,因此再添加 14 个左右的字符会使缓冲区溢出,并且根据崩溃报告,它设法丢弃堆栈 — 这称为 @987654321 @。现在看起来很简单——但这只是因为您向我们展示了实际崩溃的代码!
标签: c string char printf strcat