【问题标题】:Accessing members of dynamically allocated array of pointers to structs访问动态分配的指向结构的指针数组的成员
【发布时间】:2021-03-14 18:11:01
【问题描述】:

我需要一个全局动态指针数组,我将在其中存储我的结构,因为稍后我需要遍历这个数组以列出所有存储的信息,我还需要能够读取@987654321 @、agejob 来自控制台的变量,并将它们存储在 person_titerator 数组中。

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

typedef struct Person
{
    char name[30];
    int age;
    char job[30];
} person_t;

person_t **iterator;
int capacity = 10;
int size = 0;

int main()
{
    int i;
    *iterator = (person_t *)malloc(capacity * sizeof(person_t));
    for (i = 0; i < capacity; ++i)
    {
        person_t p;
        p.age = i;
        *iterator[i] = p;
    }
    return 0;
}

我在编译此代码 (gcc -ansi -pedantic -Wall -Wextra) 时没有收到任何错误/警告,但是当我尝试运行它时,我会立即收到 Segmentation fault

【问题讨论】:

  • 不需要投malloc

标签: arrays c pointers struct malloc


【解决方案1】:

当你这样做时:

*iterator = (person_t *)malloc(capacity * sizeof(person_t));

您正在尊重 iterator,但是作为文件范围指针变量,它被初始化为 NULL。尝试取消引用 NULL 指针会调用 undefined behavior

我怀疑您真正想要的是结构数组,而不是结构指针数组。既然如此,将iterator定义为:

person_t *iterator;

然后你像这样为它分配内存:

iterator = malloc(capacity * sizeof(person_t));

然后像这样分配给数组元素:

iterator[i] = p;

【讨论】:

    【解决方案2】:

    您声明的目的是创建一个“全局动态指针数组,我将在其中存储我的结构”。您的代码的以下修改(请参阅 cmets)将执行此操作:

    person_t p[10] = {0};
    
    int main()
    {
        int i;
        // with declaration: person_t **iterator = NULL;, 
        //following is all that is needed to create an array of pointers:
        iterator = malloc(capacity * sizeof(person_t *));//no need to cast return of malloc
       
            
            for (i = 0; i < capacity; ++i)
            {
                //person_t p;//moved to scope that will exist outside of main()
                p[i].age = i;
                iterator[i] = &p[i];//assign the address of the object to the pointer
                                 //iterator[i] is the ith pointer in a collection of 
                                 //pointers to be assigned to point to 
                                 //instances of struct person_t 
            }
            //Once all fields are populated (to-do), the following will display the results:
            for (i = 0; i < capacity; ++i)
            { 
               printf("%d) Name: %s Age: %d  Job: %s\n",  i, iterator[i]->name,iterator[i]->age,iterator[i]->job);
            }
    
        return 0;
    }
    

    【讨论】:

    • 值得指出的是,“迭代器”确实是用词不当,因为它是 person_t 集合的主要存储。 people 会更有意义,然后声明一个 person_t *iterator 用作临时指针,以实际迭代 people 的集合。
    • @DavidC.Rankin - 我不反对。然而,我在这里的尝试是对 OP 的要求使用严格的字面解释,并在此过程中坚持使用 OP 变量描述,从而允许 OP 通过我的实施步骤轻松跟踪请求中的项目。使用 OP 命名约定有助于实现这一目标。
    • 我了解,并且我同意这有助于跟踪问题中使用的命名。这就是为什么我没有建议进行更改,只是值得指出,因此至少他们认识到描述性命名是有帮助的。评论就行了。
    【解决方案3】:

    你没有正确分配内存

    首先你需要为一个指针分配内存,该指针可以存储capacity地址的数量,即通过iterator = malloc(capacity * sizeof(person_t*));完成,然后你需要分配内存来保存每个结构元素,即iterator[i] = malloc(sizeof(person_t));

    一旦我们完成了所有malloc'ed 内存应该是free'd。

    另外,还没有对malloc's 进行错误检查,这留给你做练习。

    int main()
    {
        int i;
        // test data
        char *names[] = {"ABC", "DEF"};
        char *jobs[] = {"Accountant", "Security"};
        int ages[] = {50, 60};
        
        // first allocate memory for iterator , which can hold pointers to store iterator poniters
        iterator = malloc(capacity * sizeof(person_t*)); 
        
        for (i = 0; i < capacity; ++i)
        {
            // now allocate memory for individual iterator
            iterator[i] = malloc(sizeof(person_t)); 
            strcpy(iterator[i]->name,names[i]);
            iterator[i]->age = ages[i];
            strcpy(iterator[i]->job, jobs[i]);
        }
        
        for (i = 0; i < capacity; ++i)
        {
            printf("name = %s ", iterator[i]->name);
            printf("Age = %d ", iterator[i]->age);
            printf("Job = %s\n", iterator[i]->job);
        }
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 2022-11-01
      • 2013-04-18
      • 1970-01-01
      • 2023-03-12
      • 2021-12-14
      相关资源
      最近更新 更多