0

I have a header class containing the following struct definitions:

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

typedef struct Entry Entry;

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

typedef struct Heap Heap;

And, I'm trying to write a function makeHeap that "returns a pointer to some newly allocated Heap with the given capacity, a size of 0, and an elements array allocated with the given capacity."

The elements array is what I'm not entirely sure about. It's supposed to contain pointers (references) to Entry objects. Which I am not sure if I'm doing correctly here. In order to make an array that holds references to Entry objects, I declare a double pointer array (due to the Entry having a pointer in it) and then I initialize elements iteratively, and then set my newly created heap's elements pointer to a pointer of the **elements array I just built.

I'm not getting any compile errors, but I honestly don't know if I am doing this correctly. Any input would be greatly appreciated. I did some searches but couldn't find the case where a struct was defined quite in the way mine is with the double pointer array Entry** elements.

Also, as far the syntax between Entry** elements and Entry **elements are these interchangeable? As in they are both declaring an array that holds double pointers of type 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
  • Your elements array is actually allocated on the stack when you call the makeHeap function. This is actually incorrect, since when the function returns, the array will be removed from the stack, so then your heap instance will point to location on the stack that no longer exists. You can solve this by also creating your elements array on the heap. Commented Mar 10, 2019 at 23:00
  • @wuppie367 thank you for pointing this out to me! Commented Mar 11, 2019 at 0:00

2 Answers 2

1

you'll need to malloc the elements of the heap as well, you can't just assign an array to it in a function as it will become invalid once the makeHeap() function exit. Here's your code with the correction:

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;
}

Note: Make sure to free everything once you are done with it:

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);
Sign up to request clarification or add additional context in comments.

5 Comments

Great answer. I forgot to mention the need to free the heap memory as you did.
@Mini Thanks. Since I can't comment on your answer, it might be good to add the distinction between Entry** elements[capacity]; and Entry** elements = malloc(sizeof(Entry*) * capacity) . The first will be allocated on the stack and the second on the heap, which makes a huge difference when it comes to the variable lifetime.
Thank you so much for the clarification, I've been struggling with this thing for a while and was getting no where with numerous searches. Really appreciated.
@CSmizzle No problem. Could you please accept the answer as the solution? I'm new and I want to get more reputation points! :) Thanks!
@AntoineLambert absolutely! The least I can do. Thanks again!
0

You seem to have never allocated memory for elements of type Entry**. The position of the asterisks does NOT matter to answer that last question! They are declaring double pointers so really declaring 2D arrays or an array of Entry pointers, NOT "an array that holds double pointers of type Entry".

Entry** elements[capacity]; should be Entry** elements[capacity] = malloc(sizeof(Entry*) * capacity) as well.

1 Comment

Appreciate the clarification here as well. An array of Entry pointers makes a lot more sense than what I thought it was.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.