为什么这个简单的 strcat 在运行时会崩溃?

Why is this simple strcat crashing at runtime?

出于某种原因,在多年未使用 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 中分配足够的 space 来保存初始字符串和附加字符串,因此出现缓冲区溢出。问题是,您已经从 main() 函数中删除了 return 堆栈,因此当您从 main() 程序中 return 时,程序会失控并崩溃。您可能会发现,如果将 return 0; 替换为 exit(0);,您的程序将不再崩溃。这是巧合 - 不是推荐的修复方法。

故事的寓意是"make sure there's enough space for the strings you append"!

合理的解决方法是将 clibdir 的大小从 50 增加到至少 60。


…并且…当你提出问题时,确保你在问题中显示的代码实际上崩溃了,就像你在你的机器上 运行 的代码一样。问题的原始版本有:

char clibdir[50] = "\libraries\c";

而不是:

char clibdir[50] = "C:\Users\______000\Desktop\nodeC\libraries\c";

而且没有人能理解为什么代码会崩溃 — 因为,事实上,原始代码不应该崩溃。