在C中返回包含本地指针的结构

在C中返回包含本地指针的结构,c,arrays,memory-management,struct,C,Arrays,Memory Management,Struct,在C中返回包含本地数组的结构是否有效 例如: // Define a string type typedef struct { char* c_str; } string; // Function to append 2 strings string string_append(string str1, const string str2) { // Create a local array char buffer[strlen(str1.c_str) + strle

在C中返回包含本地数组的结构是否有效

例如:

// Define a string type
typedef struct {
    char* c_str;
} string;

// Function to append 2 strings
string string_append(string str1, const string str2) {

    // Create a local array
    char buffer[strlen(str1.c_str) + strlen(str2.c_str) + 1];

    strcpy(buffer, str1.c_str);
    strcat(buffer, str2.c_str);

    // Store a pointer to the local array in a struct
    string ret = { buffer };

    return ret;
}

int main(int argc, char* argv[]) {

    string str1 = { "hello" };
    string str2 = { "goodbye" };
    string str3 = string_append(str1, str2);
}

执行
string\u append
后,
str3
的内容是否有效?

函数返回后,
缓冲区的内容未定义。如果您想在函数内部创建可以存在于函数外部的内容,则需要使用
malloc
(或等效的内容)对其进行分配。

好的,如注释中所述,您不能这样做。但是为什么呢

答案是你的代码

char buffer[strlen(str1.c_str) + strlen(str2.c_str) + 1];

正在分配自动存储,也就是说,它是作为堆栈的一部分创建的,该堆栈还包含函数的返回地址和参数。因此,当您从函数返回时,分配的空间在您尝试使用它时可能会损坏,也可能不会损坏,但很可能会损坏。

您的
缓冲区
字符数组是在函数内部创建的。在函数中创建的变量的默认存储类是
自动

这意味着,变量将作为堆栈的一部分创建。然而,当函数返回并且控制权转移到调用函数时,如果在这种情况下,调用函数调用另一个函数,那么该堆栈将很快被修改。例如,如果在
string\u append()
函数之后调用
printf()
。为
printf()
创建的堆栈将覆盖字符串str3的
char*c_str指针指向的位置。它会打印一些垃圾值


试试看

您的结构不包含数组:它包含指针。有关数组和指针之间差异的更多信息,请参阅的第6节。我将澄清这个问题。我要问的是,结构指向的数组的内容是否会被破坏?它们将无效。你不能这样做。这很令人失望……它有一个很好的理由不这样做。如果我返回一个使用malloc分配的变量,我怎么能轻松地确保使用我的函数的任何人都知道需要释放它?@tjwrona1992:通过提供写得很好的文档。@alk:我仍然觉得从函数返回malloced变量只是一个内存泄漏即将发生在一些缺乏经验的开发人员手中。