如何使用realloc为结构中的数组分配内存?

时间:2018-07-09 23:43:47

标签: c struct

为什么我不能以这种方式为数组x.a分配内存?编译器说x.a没有在main中初始化,但是我想在函数fun中初始化数组。在此函数中,我要为第一个元素创建内存并将其放入数组,为第二个元素创建内存并使其放入数组等。我应该在此代码中进行哪些更改?

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

typedef struct {
  int *a;

} array;

void fun(int *a,int num)
{
  int i;

  for(i=0;i<num;i++)
  {
    a=(int*)realloc(a,(i+1)*sizeof(int));
    scanf("%d",(a+i));
  }
}
int main(int argc,char *argv[]) 
{
  array x;
  int i,num;

  scanf("%d",&num); //number of elements in array *a (in struct)

  fun(x.a,num);

  for(i=0;i<num;i++)
   printf("%2d",x.a[i]); //prints elements
}

2 个答案:

答案 0 :(得分:3)

就像您需要传递num地址并为其分配scanf一样,您也需要传递x.a的地址(并相应地更改匹配参数的类型,并在a内部使用fun,以便从fun内部进行分配。

答案 1 :(得分:2)

您有两个问题。首先是x.a在使用前未设置为值。您可以在x的开头定义main

array x;

这将创建x,但不添加任何内容。然后,您将x.a传递给fun

fun(x.a,num);

这表示将x.a传递给fun。但是x.a还没有值,所以这是错误的。 (顺便说一下,使您的代码可读。在逗号和分号后放置空格,与普通英文文本相同。)

然后,在fun中,在以下位置使用a

a=(int*)realloc(a,(i+1)*sizeof(int));

第一次执行时,a的值不正确,因为它是从x.a传递来的,从未设置过。 realloc用于重新分配现有分配。您必须将初始化的指针值传递给它。 (其中包括NULL;您可以将其传递给NULL,以表示您要执行初始分配而不是重新分配。)

解决这些问题的最简单方法是给x.a赋予一个初始值,您可以通过将x的定义更改为:

array x = { NULL };

第二个问题是fun从未将更新后的值传递回其调用方。您对fun的声明是:

void fun(int *a,int num)

这表示fun接受一个指向int指针的值。通过以下方式调用fun时:

fun(x.a,num);

仅传递x.a的值。实际对象x.a不会传递,而只是其值传递。因此fun无法为x.a返回新值。有两种方法可以解决此问题。一种是更改fun以接受指向x.a的指针:

void fun(int **a,int num)

并更改main例程以传递x.a的地址:

fun(&x.a,num)

并将afun的每次使用更改为*a

*a=(int*)realloc(*a,(i+1)*sizeof(int));
scanf("%d",(*a+i));

另一种方法是返回新指针作为fun的返回值。将fun的声明更改为:

int *fun(int *a,int num)

并在main返回时更改x.a以更新fun

x.a = fun(x.a,num);

并通过在末尾插入以下语句,更改fun以返回值(不要将a更改为*a):

return a;

完成后,您的程序将在很大程度上运行,但是您还应该解决两个问题:

  • 当您已经知道所需的最终大小时,重复realloc是浪费的。您应该只为所需的大小分配一次内存。 realloc用于更改您需要的尺寸。
  • realloc可能会失败。您应该修改代码以处理失败并返回NULL的情况。