Инициализация массива указателей на структуры, содержащие двойной указатель в c - PullRequest
0 голосов
/ 11 марта 2019

У меня есть класс заголовка, содержащий следующие определения структуры:

struct Entry {
    int key;
    char *value;
};

typedef struct Entry Entry;

struct Heap {
    int capacity;
    int size;
    Entry **elements;
};

typedef struct Heap Heap;

И я пытаюсь написать функцию makeHeap, которая "возвращает указатель на какую-то недавно выделенную кучу с заданной емкостью, размером 0 и массивом элементов, выделенным с данной емкостью."

Массив elements - это то, в чем я не совсем уверен. Он должен содержать указатели (ссылки) на объекты Entry. Что я не уверен, правильно ли я делаю здесь. Для создания массива, который содержит ссылки на объекты Entry, я объявляю массив двойных указателей (из-за того, что Entry имеет указатель в нем), а затем итеративно инициализирую элементы, а затем устанавливаю указатель на элементы вновь созданной кучи на указатель массив ** элементов, который я только что построил.

Я не получаю никаких ошибок компиляции, но, честно говоря, не знаю, правильно ли я это делаю. Любой вклад будет принята с благодарностью. Я провел некоторые поиски, но не смог найти случай, когда структура была определена так, как моя с массивом двойных указателей Entry** elements.

Кроме того, насколько синтаксис между Entry** elements и Entry **elements взаимозаменяемы? Так как они оба объявляют массив, который содержит двойные указатели типа Entry?

Heap *makeHeap(int capacity) {
    //Make the heap
    Heap* theHeap = calloc(1, sizeof(Heap));
    //set its capacity to param
    theHeap->capacity = capacity;
    //inital size is 0
    theHeap->size = 0;
    //elements contains pointers (references) to Entry objects.
    Entry **elements[capacity];
    //iterate capacity times allocating an entry reference for each element to be placed
    int i = 0;
    for (; i < capacity; i++) {
       elements[i] = calloc(1, sizeof(Entry));
    }

    theHeap->elements = *elements;

    return theHeap;
}

Ответы [ 2 ]

1 голос
/ 11 марта 2019

вам также нужно распределить элементы кучи, вы не можете просто присвоить ей массив в функции, так как он станет недействительным после выхода из функции makeHeap (). Вот ваш код с исправлением:

Heap* makeHeap(int capacity) {
//Make the heap
Heap* theHeap = calloc(1, sizeof(Heap));
//set its capacity to param
theHeap->capacity = capacity;
//inital size is 0
theHeap->size = 0;
//elements contains pointers (references) to Entry objects.
theHeap->elements = calloc(capacity,sizeof(Heap*));
//iterate capacity times allocating an entry reference for each element to be placed
int i = 0;
for(; i < capacity; i++) {
   theHeap->elements[i] = calloc(1, sizeof(Entry));
}

return theHeap;
}

Примечание: Обязательно освободите все, как только вы закончите с ним:

Heap* test = makeHeap(10);

//Do your stuff with the heap...

for(size_t i = 0;i<test->capacity;i++){
        //Note: free the 'char* value' if you malloced them
    free(test->elements[i]);
}
free(test->elements);
free(test);
0 голосов
/ 11 марта 2019

Вы, кажется, никогда не выделяли память для elements типа Entry**.Положение звездочек НЕ имеет значения, чтобы ответить на этот последний вопрос!Они объявляют двойные указатели, поэтому действительно объявляют двумерные массивы или массив указателей Entry, а не «массив, который содержит двойные указатели типа Entry».

Entry** elements[capacity]; также должно быть Entry** elements[capacity] = malloc(sizeof(Entry*) * capacity).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...