C: структура указатель-массив - PullRequest
0 голосов
/ 08 декабря 2018

Я пытаюсь создать и инициализировать указатель на массив указателей на структуры.Этот массив будет передан во многие части моей программы.

Это мой код:

file.h

#ifndef FILE_H
#define FILE_H

typedef struct Object Object;

void init(Object*** objs);

#endif

file.c

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

struct Object
{
    int a, b;
};

void init(Object*** objs)
{
    *objs = malloc(5 * sizeof(Object*));

    for(int i = 0; i < 5; i++)
    {
        *objs[i] = malloc(sizeof(struct Object));
        *objs[i] -> a = i;     // arbitrary member access
        *objs[i] -> b = i * 2; // arbitrary member access
    }

}

main.c

#include "file.c"

int main(int argc, char** argv)
{
    Object** prog_objs;

    init(&prog_objs);
    // should now have a pointer to an array to pass around

    for(int i = 0; i < 5; i++)
    {
        printf("Obj: %d, %d\n", prog_objs[i] -> a, prog_objs[i] -> b);
    }

    return 0;
}

Я не совсем уверен, почему это не работает.Я уверен, что мой main() правильный, и проблема где-то в функции init().Я пробовал различные способы инициализации элементов массива в качестве указателей на структуры, но я продолжаю получать ошибки компиляции или ошибки segfaults.

Любые советы о том, где мои проблемы, очень ценятся!Спасибо

Ответы [ 3 ]

0 голосов
/ 08 декабря 2018

*objs[i] не означает, что вы думаете, что означает , это означает:

*(objs[i])

Разыменование элемента в позиции i ... Но вам нужно:

(*obj)[i]

Что означает разыменование obj, затем доступ к разыменованному элементу ...

Относительно того, почему это происходит, это связано соператор [] имеет более высокий приоритет, чем оператор * ... Итак, оператор [] сначала выполняет оценку, а затем оператор * выполняет ...

Еще один способ решения вашей проблемы.проблема заключается в:

obj[0][i]
0 голосов
/ 08 декабря 2018

@melpomene уже ответил на этот вопрос, поскольку проблема возникает из-за приоритета оператора .

Поскольку функция init() выполняет распределение, а также инициализацию,Чтобы избежать подобных проблем, вы можете изменить init(), чтобы он возвращал тип Object** вместо того, чтобы принимать Object*** objs в качестве параметра.Вы можете сделать:

Object** init(void)
{
    Object** objs;
    objs = malloc(5 * sizeof(Object*));
    if (objs == NULL) {
       fprintf(stderr, "Failed to allocate memory");
       exit(EXIT_FAILURE); //You can  return NULL from here and handle it in calling function
    }

    for(int i = 0; i < 5; i++)
    {
        objs[i] = malloc(sizeof(struct Object));
        if (objs[i] == NULL) {
           fprintf (stderr, "Failed to allocate memory");
           exit(EXIT_FAILURE);
        }
        objs[i] -> a = i;     // arbitrary member access
        objs[i] -> b = i * 2; // arbitrary member access
    }
    return objs;
}

В функции вызова вы можете сделать:

Object** prog_objs = init();

Кроме того, следуйте хорошей практике программирования.Всегда проверяйте malloc возврат и гарантируйте free выделенную память, как только вы закончите с ней.

0 голосов
/ 08 декабря 2018

*objs[i] - ошибка приоритета.Он обрабатывается как *(objs[i]).

. Вместо него должно быть (*objs)[i].

...