当输入超过39个字符时,使用strdup和strcat创建文件路径的程序崩溃

Dan*_*izo -1 c++ arrays char

我试图使用函数strcat()连接两个char数组.然而程序崩溃了.

#include <cstdio>
#include <cstring>

int main() {
    const char *file_path = "D:/MyFolder/YetAnotherFolder/test.txt";
    const char *file_bk_path = strcat(strdup(file_path), ".bk");
    printf("%s\n", file_bk_path);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

对我来说最奇怪的是程序在崩溃之前确实产生了一个输出:

d:/MyFolder/YetAnotherFolder/test.txt.bk

这个问题的原因是什么以及如何修复?

在Windows(MinGW 7.2.0)中重现错误状态.

Fan*_*Fox 5

strdup正在为您创建新内存以保存字符串的副本.记忆只有strlen(file_path) + 1.然后尝试将额外的2个字符添加到您不拥有的内存中.您将超出创建的内存范围并创建一些未定义的行为.它可能会打印,因为设置内存和打印第一部分可能会正确发生,但它是未定义的,任何事情都可能发生.另请注意,strdup您需要调用free它为您创建的内存,否则您将泄漏一些内存.

这是一个更简单的方法,使用std::string:

const char *file_path = "D:/MyFolder/YetAnotherFolder/test.txt";
std::string file_bk_path = std::string(file_path) + ".bk";
std::cout << file_bk_path << "\n";
Run Code Online (Sandbox Code Playgroud)

这是一个实例.

如果它绝对需要是in- Cstyle,那么你最好自己控制内存:

const char *file_path = "D:/MyFolder/YetAnotherFolder/test.txt";
const char *bk_string = ".bk";
char *file_bk_path = malloc((strlen(file_path) + strlen(bk_string) + 1)*sizeof(char));
if (!file_bk_path) { exit(1); }
strcpy(file_bk_path, file_path);
strcat(file_bk_path, bk_string);
printf("%s\n", file_bk_path);
free(file_bk_path);
Run Code Online (Sandbox Code Playgroud)

这是一个实例.