返回指向结构数组的指针

时间:2018-07-26 01:43:26

标签: c pointers memory struct malloc

假设我必须创建一个在堆上分配的结构数组,并返回一个指向该结构数组的指针。

typedef struct Pair {
    int x;
    int y;
} Pair;

Pair** foo(int n, int m, int length)
{
    Pair* arr = malloc(sizeof(*arr) * length);

    for (int i = 0; i < length; ++i) {
        arr[i].x = n++;
        arr[i].y = m++;
    }

    return &arr;
}

当我编译包含此功能的程序时,它警告我正在返回局部变量的地址。我认为这是因为指针是在函数内初始化的(即在堆栈上),因此它被视为局部变量。

当我编译它,而忽略此警告并继续运行它时,访问返回的指针时程序崩溃。

我尝试过动态分配指针:

Pair** ptr = malloc(sizeof(**ptr));
ptr = &arr;
...
return ptr;

,但是访问此指针时程序仍然崩溃。如何在函数中创建此数组并返回指向该数组的指针,以便可以安全地访问它?

4 个答案:

答案 0 :(得分:4)

此数组在堆栈上初始化,但是指针(arr)是局部变量,因此调用方main无法访问它。您不需要使用指针的地址。您可以使用指针本身访问数组。

Pair* foo(int n, int m, int length)
{
    Pair* arr = malloc(sizeof(*arr) * length);

    for (int i = 0; i < length; ++i) {
        arr[i].x = n++;
        arr[i].y = m++;
    }

    return arr;
}

答案 1 :(得分:1)

如果需要结构的数组,则代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int x;
    int y;
} Pair;

static Pair* foo(int n, int m, int length)   {
    Pair* arr = malloc(sizeof(*arr) * length);
    for (int i = 0; i < length; ++i) {
        arr[i].x = n++;
        arr[i].y = m++;
    }
    return arr;
}

int main(void) {
    Pair *z = foo(111, 222, 3);
    for (int i = 0; i < 3; ++i) 
        printf("z[%d]= { %d, %d }\n", i, z[i].x, z[i].y);
    free(z);
    return 0;
}

给出输出:

z[0]= { 111, 222 }
z[1]= { 112, 223 }
z[2]= { 113, 224 }

答案 2 :(得分:-1)

如果要指向结构数组的指针,可以将函数签名从Pair**更改为Pair*


如果您仍然想要一个指向指针数组的指针,则为Pair的每个索引分配一个arr结构的内存。

for(int i = 0; i < length; ++i){
    arr[i] = malloc(sizeof(Pair));
    ...
}

您可以将&arr声明为

而不是返回arr
Pair** arr = malloc(sizeof(Pair*) * length);

答案 3 :(得分:-1)

由于arr是局部变量,所以foo结束时它将是空闲的。因此,之后您将无权访问arr。为了解决这个问题,您应该在堆中声明数组指针:

     Pair** foo(int n, int m, int length)
     {
           Pair ** arr = (Pair**)malloc(sizeof(Pair*));
           *arr = malloc(sizeof(Pair) * length);

           for (int i = 0; i < length; ++i) {
               (*arr)[i].x = n++;
               (*arr)[i].y = m++;
           }

            return arr;
       }