1

我正在尝试返回一个 char 指针数组,但编译器似乎不喜欢它。

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

编译器错误如下:

error: expected identifier or '(' before '[' token 

在线 1

知道为什么编译器不喜欢它以及如何修复它吗?
(我知道我也可以从调用者那里传入一个结构来存储返回指针,但我想避免这样做)

4

3 回答 3

2

Allow me to add to @Lidong Guo's answer (quoted below)

You can't create a array by :char * tmp[x],since x is known runtime!

use char **tmp = malloc(x*sizeof(char *)); instead

By looking at your code, I can see that you have misunderstood either what the array label tmp actually represents or where tmp is actually located.

When you allocate a variable (or an array of static size) in a function, it is stored on the stack, in your current stack frame. This stack frame is destroyed/freed as soon as the function returns and you should NOT be using/referencing that memory any more!!!

tmp is a label that represents the memory address at which the tmp array is located. This is on the stack so when your function returns it is no longer a valid pointer!

Forgive me if you already know this but judging by your terminology I suspect you might not.

In C you CAN NOT assign arrays to other arrays!

int array1[10], array2[10];

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

array2 = array1; // ILLEGAL! DOES NOT COPY AN ARRAY

Similarly, if you return tmp you are returning the address, NOT the array so if you are assigning it to another variable you should be copying it instead of assigning it!

Hence C does not allow you to return an array and you should be returning pointers instead.

But even when you return a pointer to tmp you will be in trouble because of the way you are trying to allocate it (on the stack) so @Lidong Guo suggested that you allocate it on the Heap where it can live even after your function returns. However, this means that you will need to remember to free that memory!

So a rewrite of your function using @Lidong Guo's code would look like

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;
}

And a hypothetical main would use it like so:

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;
}
于 2013-08-01T01:16:47.580 回答
1

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

  1. 函数类型
  2. 数组类型

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

为了帮助内存管理,它也可能有助于创建一个free_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 */
}
于 2013-08-01T01:46:42.940 回答
0

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

char **tmp = malloc(x*sizeof(char *));改为使用

于 2013-08-01T01:01:30.003 回答