如何在函数中填充结构数组

时间:2018-12-31 18:06:15

标签: c pointers struct dynamic-memory-allocation

我试图在外部函数“ add”中创建结构的数组,并打印它的字段,但是当我回到主函数“ arr”时,它仍然为NULL。 我很困惑,因为我已经在外部函数中创建数组很多次了,但是它确实起作用了..也许这次动态内存分配使事情变得混乱了。我可以在这件事上得到建议吗? 谢谢!

typedef struct {
    char* id;
    char gender;
    char *name;
}Member;

void add(Member arr[], int size);
void print(Member arr[], int *size);

int main()
{
    char temp[100];
    int size=0;
    Member *arr = NULL;
    Member *data = (Member*)malloc(sizeof(Member));
    //scan fields
    gets(temp);
    data->id = (char*)malloc((strlen(temp) + 1) * sizeof(char));
    strcpy(data->id, temp);
    gets(temp);
    data->gender = temp;
    gets(temp);
    data->name = (char*)malloc((strlen(temp) + 1) * sizeof(char));
    strcpy(data->name, temp);

    add(data, &arr, &size);
    print(arr, &size);
    return 0;
}

void add(Member *data, Member arr[], int *size) 
{
    arr = (Member*)realloc(arr, (*size + 1) * sizeof(Member));
    arr[*size] = *data;
}

void print(Member arr[], int *size)
{
    for (int i = 0;i < *size;i++)
    {
        puts(arr->id);
        puts(arr->gender);
        puts(arr->name);
    }
}

1 个答案:

答案 0 :(得分:0)

想象这样的代码:

#include <stdio.h>

void f(int i){
  i++;
}

int main(){
  int i = 3;
  f(3);
  printf("%d\n", i);
}

我们都知道f()增加了i本地副本,而不是传递给f()来初始设置该值的变量。说完这些,让我们再来看一下您的add()

void add(Member *data, Member arr[], int *size) 
{
    arr = (Member*)realloc(arr, (*size + 1) * sizeof(Member));
    arr[*size] = *data;
}

arr传递给函数时,它包含当前arr的内存地址,该地址以NULL开头。但是,就像我们在上述i中更改f()的本地值时一样,在arr中将add()设置为新值只会更改本地值。它不会更改main()的{​​{1}}。

我们还知道,如果我们向函数传递要更改其数据的地址,则该函数可以更改该 address 处的数据和该地址将反映调用函数中的更改:

arr

当您要更改 pointer 的值时,会应用相同的逻辑(尽管会变得更加混乱)。发送该 pointer 的地址!让我们从一个非常简单的案例开始:

#include <stdio.h>

void f(int * i){
  *i = *i + 1;
}

int main(){
  int i = 3;
  f(&i);
  printf("%d\n", i);
}

在这里,我们在main中创建一个指向#include <stdio.h> #include <stdlib.h> void f(int** i){ *i = (int*)malloc(sizeof(int)); **i = 99; } int main(){ int *i = NULL; f(&i); printf("%d\n", *i); } 的指针,并将其初始化为NULL。然后,我们将该指针的地址 (即我们存储了NULL的地址)发送到int,该地址(就像您的程序中一样)分配了一些内存,并放置了新指针的地址。在main的f()的地址处分配了指针_。现在,存储在i的数据已更改,并且从&i解引用i将解引用新分配的地址。

在代码中,就像在我的代码中一样,您必须更改将main()传递给arr的方式以及与之交互的方式-您将获得一种练习充分考虑自己。简而言之,这样的事情应该可以帮助您入门:

  1. 传递add() add的地址,而不是它存储的地址。
  2. 将重新分配的内存的新地址存储回相同的地址,即arr
  3. 确保更新&arr以将指针解除对指针两次的引用,以将成员设置为存储在地址add()的地址。