C 编译器在返回字符指针数组时发出抱怨

C 编译器在返回字符指针数组时发出抱怨,c,string,pointers,char,C,String,Pointers,Char,我试图返回一个字符指针数组,但编译器似乎不喜欢它 char*[] get_multiple(int x) { char *tmp[x]; int i; for (i=0;i<x;i++) tmp[i]=strdup("abc"); return tmp; } 在线1 知道编译器为什么不喜欢它以及如何修复它吗? (我知道我也可以从调用方传入一个结构来存储返回指针,但我想避免这样做)您不能通过以下方式创建数组:char*tmp[x],因为x是已

我试图返回一个字符指针数组,但编译器似乎不喜欢它

char*[] get_multiple(int x) {
    char *tmp[x];
    int i;
    for (i=0;i<x;i++)
        tmp[i]=strdup("abc");
    return tmp;
}
在线1

知道编译器为什么不喜欢它以及如何修复它吗?

(我知道我也可以从调用方传入一个结构来存储返回指针,但我想避免这样做)

您不能通过以下方式创建数组:
char*tmp[x]
,因为x是已知的运行时


使用
char**tmp=malloc(x*sizeof(char*))相反

请允许我补充@Lidong Guo的答案(以下引用)


您不能通过以下方式创建数组:
char*tmp[x]
,因为x是已知的运行时

使用
char**tmp=malloc(x*sizeof(char*))取而代之

通过查看您的代码,我可以看出您误解了数组标签
tmp
实际代表的内容或
tmp
的实际位置

在函数中分配变量(或静态大小的数组)时,它存储在当前堆栈帧中的堆栈中。一旦函数返回,此堆栈帧将被销毁/释放,您不应再使用/引用该内存

tmp
是一个标签,表示
tmp
数组所在的内存地址。这在堆栈上,因此当函数返回时,它不再是有效指针

原谅我,如果你已经知道这一点,但从你的术语判断,我怀疑你可能不知道

在C中,不能将数组分配给其他数组

int array1[10], array2[10];

// ... Put some values into array 1 ...

array2 = array1; // ILLEGAL! DOES NOT COPY AN ARRAY
同样,如果返回
tmp
则返回的是地址,而不是数组,因此如果将其分配给另一个变量,则应复制它,而不是分配它

因此,C不允许返回数组,而应该返回指针

但是,即使您返回指向
tmp
的指针,您也会遇到麻烦,因为您试图分配它的方式(在堆栈上),因此@Lidong Guo建议您将它分配到堆上,即使在您的函数返回后,它仍然可以生存。但是,这意味着您需要记住才能释放内存

因此,使用@Lidong Guo的代码重写函数

char** get_multiple(int x) {
    char **tmp = malloc(x * sizeof(char*));
    int i;
    for (i=0;i<x;i++)
        tmp[i]=strdup("abc");
    return tmp;
}

有两种类型不能用作函数的返回类型:

  • 功能类型
  • 数组类型
  • 您需要做的是声明一个函数,该函数返回指向char的指针,或
    char**
    。必须分配足够的内存来存储指向字符串的指针-因此,如果需要7个字符串,则必须分配足够的空间来容纳至少7个
    char*
    对象-然后必须为7个字符串中的每个字符串分配空间,并将其分配给刚刚分配的
    char*
    。或者,如果此数组中的所有字符串都具有最大长度,则可以声明一个连续内存块并计算每个字符串的偏移量

    为了帮助内存管理,还可以创建一个
    free\u multiple
    函数

    char **get_multiple(size_t max)
    {
        char **multiple = malloc(max * sizeof(*multiple));
        for (size_t i = 0; i < max; i++)
            multiple[i] = malloc(/* determine max length of string including null terminator */);
        return multiple;
    }
    
    void free_multiple(char **multiple, size_t max)
    {
        for (size_t i = 0; i < max; i++)
            free(multiple[i]); /* free individual strings */
        free(multiple); /* free the container as well */
    }
    
    char**get\u倍数(最大大小)
    {
    字符**倍数=malloc(最大*大小(*倍数));
    对于(尺寸i=0;i
    我建议不要这样做!求你了,求你了,不要那样返回数组!它被分配到堆栈上,一旦函数返回,它的内存将被“释放”。此外,阵列不会复制到您的目标!!!你不能把一个数组分配给一个数组,它不是那样工作的!!!实际上返回的是一个指向strdup从堆中分配的内存块的指针。对不起,我的评论很简短,我已经在回答您的问题时表达了我的担忧。我希望它能解释我上面的意思。@user967850不正确。返回的是一个本地自动变量,其内容是指向已分配内存的指针数组。变长数组作为C语言的一部分已有近14年的历史。
    int main()
    {
        char** multiple7;
    
        multiple7 = get_multiple(7);
    
        // Do some stuff on multiple 7
        free(multiple7[3]);
    
        // Do some more stuff ...
    
        // Don't forget to free multiple7 array memory too
        free(multiple7);
    
        return 0;
    }
    
    char **get_multiple(size_t max)
    {
        char **multiple = malloc(max * sizeof(*multiple));
        for (size_t i = 0; i < max; i++)
            multiple[i] = malloc(/* determine max length of string including null terminator */);
        return multiple;
    }
    
    void free_multiple(char **multiple, size_t max)
    {
        for (size_t i = 0; i < max; i++)
            free(multiple[i]); /* free individual strings */
        free(multiple); /* free the container as well */
    }