使用指针返回结构数组

时间:2009-11-29 02:35:44

标签: c arrays data-structures pointers return

    typedef struct unit_class_struct {
        char *name;
    } person;



person * setName() {
       person * array;
       array = malloc (2 * sizeof(person));

       array->name = strdup("Robert");
       array++;
       array->name = strdup("Jose");
       return array;
}


    int main()
    {
        person *array;

        array = setName();

        printf("First name is %s\n", array[0].name);
        printf("Second name is %s\n", array[1].name);

        return 0;
    }

在这个例子中,array [0] .name返回Jose,而不是我预期的Robert,而array [1] .name是空的。

但是,如果我使用

person * setName() {
       person * array;
       person * array_switch;
       array = malloc (2 * sizeof(person));
       array_switch = array;
       array_switch->name = strdup("Robert");
       array_switch++;
       array_switch->name = strdup("Jose");
       return array;
}

它按预期工作。 array.name [0]返回Robert,array.name [1]返回Jose。

为什么它需要第二个指针才能使用此示例?我可以不使用第二个指针而仍然使用指针算法吗?

我已经知道这是另一种方法:

person * setName() {
       person * array;
       array = malloc (2 * sizeof(person));
       array[0].name = strdup("Robert");
       array[1].name = strdup("Jose");
       return array;
}

5 个答案:

答案 0 :(得分:18)

在您的代码中:

person * setName() {
   person * array;
   array = malloc (2 * sizeof(person));

   array->name = strdup("Robert");
   array++;
   array->name = strdup("Jose");
   return array;
}

为数组中的两个元素分配空间,并将array设置为指向第一个:

+-------+      +----------+
| array | ---> | array[0] |
+-------+      +----------+
               | array[1] |
               +----------+

然后用array++递增元素指针,最后返回到调用函数。该指针指向第二个数组元素,这就是为什么它似乎是错误的(为什么当你试图在以后尝试释放该内存时几乎肯定会崩溃):

+-------+      +----------+
| array | -+   | array[0] |
+-------+  |   +----------+
           +-> | array[1] |
               +----------+

您需要的是:

person * setName() {
   person * array;
   array = malloc (2 * sizeof(person));

   array[0].name = strdup("Robert");
   array[1].name = strdup("Jose");
   return array;
}
正如你已经指出的那样。此解决方案根本不会更改array指针。但是,如果你真的想使用指针,你可以在返回之前用array++反转array--的操作,以便将array设置回正确的值:

person * setName() {
   person * array;
   array = malloc (2 * sizeof(person));

   array->name = strdup("Robert");
   array++;
   array->name = strdup("Jose");
   array--;
   return array;
}

或者,另一种不改变原始指针的方法,不使用数组索引而不使用第二个指针就是使用指针算法。编译器知道指针指向哪种类型,因此可以正确调整指针以找到下一个元素(您已经知道它知道如何执行此操作,因为array++array = array + 1的简写,并且该语句调整了值也正确):

person * setName() {
   person * array;
   array = malloc (2 * sizeof(person));

   (array+0)->name = strdup("Robert");
   (array+1)->name = strdup("Jose");
   return array;
}

答案 1 :(得分:2)

您只需执行简单的算术指针操作,如加法和减法:

    array->name = "Robert";
    (array+1)->name = "Jose";
    return array;

答案 2 :(得分:1)


由于您增加了array,因此您不再有指向[0]元素的指针,而是指向[1]元素的指针。这样做:

   array->name = strdup("Robert");
   array++;
   array->name = strdup("Jose");
   return array - 1;

请注意,在C p[x]中只有*(p + x),或者,如果您愿意,请考虑以下内容:(p + x)[0]。最后一种情况是您的程序实际执行的操作,x == 1.因此(p + 1)[1]p[2]相同,并且没有任何内容,因此您的结果为空。

(你也可以把它写成......

   array++->name = strdup("Robert");
   array--->name = strdup("Jose");
   return array;

...但是如果你这样做,一群人会来和你一起投票。真的难以读懂吗?我们的目标是只写出没有灵感的笨重代码?)

答案 3 :(得分:1)

指针实际上只是 数字 (内存中的地址)。您正在修改此指针以指向其他位置,然后将其返回。

答案 4 :(得分:1)

这将使用指针算法,并保留原始数组指针:

person * setName() {
       person * array;

       array = malloc (2 * sizeof(person));
       (array+0)->name = strdup("Robert");
       (array+1)->name = strdup("Jose");

       return array;
}