如何使用realloc在struct中为数组分配内存?

时间:2021-11-02 13:13:20

Why I can't allocate memory for array x.a this way? Compiler says that x.a is not initialized in main, but I want to initialize array in function fun. In this function, I want to make the memory for the first element and put it in the array, make the memory for second and put it in the array etc. What should I change in this code?

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

#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 个解决方案

#1


2  

You have two problems. The first is that x.a is not set to a value before it is used. You define x at the start of main:

你有两个问题。第一个是x.a在使用之前未设置为值。你在main的开头定义x:

array x;

That creates x but does not put anything in it. Then you pass x.a to fun in:

这会产生x但不会放入任何东西。然后你将x.a传递给fun in:

fun(x.a,num);

This says to pass the value of x.a to fun. But x.a does not have a value yet, so that is wrong. (By the way, make your code readable. Put spaces after commas and semicolons, the same as in normal English text.)

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

Then, in fun, you use a in:

然后,有趣的是,你使用in:

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

The first time that is executed, a does not have a proper value because it was passed the value from x.a, which was never set. realloc is for reallocating existing allocations. You have to pass it an initialized pointer value. (That includes NULL; you are allowed to pass it NULL to say you want to perform an initial allocation instead of a reallocation.)

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

The easiest way to fix these problems is to give x.a an initial value, which you can do by changing the definition of x to:

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

array x = { NULL };

The second problem is that fun never passes an updated value back to its caller. Your declaration of fun is:

第二个问题是,fun永远不会将更新的值传递回其调用者。您的乐趣宣言是:

void fun(int *a,int num)

This says that fun accepts a value that is a pointer to an int. When fun is called with:

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

fun(x.a,num);

only the value of x.a is passed. The actual object x.a is not passed, just its value. So fun has no way to return a new value for x.a. There are two ways to fix this. One is to change fun to accept a pointer to x.a:

只传递x.a的值。实际对象x.a不会传递,只是它的值。所以有趣无法为x.a返回新值。有两种方法可以解决这个问题。一种是改变乐趣以接受指向x.a的指针:

void fun(int **a,int num)

and change the main routine to pass the address of x.a:

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

fun(&x.a,num)

and change every use of a inside fun to *a:

并将内部乐趣的每一种用法改为* a:

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

The other way is to return the new pointer as the return value of fun. Change the declaration of fun to:

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

int *fun(int *a,int num)

and change main to update x.a when fun returns it:

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

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

and change fun to return the value (do not change a to *a as above) by inserting this statement at the end:

并通过在结尾插入此语句来更改乐趣以返回值(不要将a更改为* a):

return a;

Once that is done, your program will be largely working, but there are two more issues you ought to address:

完成后,您的程序将在很大程度上正常工作,但还有两个问题需要解决:

  • It is wasteful to realloc repeatedly when you already know the final size you want. You ought to just allocate memory once for the size you want. realloc is for when the size you need changes.
  • 当您已经知道所需的最终尺寸时,重复重新分配是浪费的。您应该只为您想要的大小分配一次内存。 realloc适用于您需要更改的大小。
  • realloc can fail. You should modify the code to handle the case when it fails and returns NULL.
  • realloc可能会失败。您应该修改代码以在失败时处理该情况并返回NULL。

#2


3  

Just as you need to pass the address of num to have scanf assign to it, you'd need to pass the address of x.a (and change the type of the matching parameter accordingly, and the use of a inside of fun) in order to assign to it from inside fun.

就像你需要传递num的地址让scanf赋值给你一样,你需要传递xa的地址(并相应地改变匹配参数的类型,以及使用内部的乐趣)以便从内心的乐趣中分配给它。

#1


2  

You have two problems. The first is that x.a is not set to a value before it is used. You define x at the start of main:

你有两个问题。第一个是x.a在使用之前未设置为值。你在main的开头定义x:

array x;

That creates x but does not put anything in it. Then you pass x.a to fun in:

这会产生x但不会放入任何东西。然后你将x.a传递给fun in:

fun(x.a,num);

This says to pass the value of x.a to fun. But x.a does not have a value yet, so that is wrong. (By the way, make your code readable. Put spaces after commas and semicolons, the same as in normal English text.)

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

Then, in fun, you use a in:

然后,有趣的是,你使用in:

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

The first time that is executed, a does not have a proper value because it was passed the value from x.a, which was never set. realloc is for reallocating existing allocations. You have to pass it an initialized pointer value. (That includes NULL; you are allowed to pass it NULL to say you want to perform an initial allocation instead of a reallocation.)

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

The easiest way to fix these problems is to give x.a an initial value, which you can do by changing the definition of x to:

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

array x = { NULL };

The second problem is that fun never passes an updated value back to its caller. Your declaration of fun is:

第二个问题是,fun永远不会将更新的值传递回其调用者。您的乐趣宣言是:

void fun(int *a,int num)

This says that fun accepts a value that is a pointer to an int. When fun is called with:

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

fun(x.a,num);

only the value of x.a is passed. The actual object x.a is not passed, just its value. So fun has no way to return a new value for x.a. There are two ways to fix this. One is to change fun to accept a pointer to x.a:

只传递x.a的值。实际对象x.a不会传递,只是它的值。所以有趣无法为x.a返回新值。有两种方法可以解决这个问题。一种是改变乐趣以接受指向x.a的指针:

void fun(int **a,int num)

and change the main routine to pass the address of x.a:

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

fun(&x.a,num)

and change every use of a inside fun to *a:

并将内部乐趣的每一种用法改为* a:

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

The other way is to return the new pointer as the return value of fun. Change the declaration of fun to:

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

int *fun(int *a,int num)

and change main to update x.a when fun returns it:

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

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

and change fun to return the value (do not change a to *a as above) by inserting this statement at the end:

并通过在结尾插入此语句来更改乐趣以返回值(不要将a更改为* a):

return a;

Once that is done, your program will be largely working, but there are two more issues you ought to address:

完成后,您的程序将在很大程度上正常工作,但还有两个问题需要解决:

  • It is wasteful to realloc repeatedly when you already know the final size you want. You ought to just allocate memory once for the size you want. realloc is for when the size you need changes.
  • 当您已经知道所需的最终尺寸时,重复重新分配是浪费的。您应该只为您想要的大小分配一次内存。 realloc适用于您需要更改的大小。
  • realloc can fail. You should modify the code to handle the case when it fails and returns NULL.
  • realloc可能会失败。您应该修改代码以在失败时处理该情况并返回NULL。

#2


3  

Just as you need to pass the address of num to have scanf assign to it, you'd need to pass the address of x.a (and change the type of the matching parameter accordingly, and the use of a inside of fun) in order to assign to it from inside fun.

就像你需要传递num的地址让scanf赋值给你一样,你需要传递xa的地址(并相应地改变匹配参数的类型,以及使用内部的乐趣)以便从内心的乐趣中分配给它。