user3674626
user3674626

Reputation: 11

C99: Return a value after it's been free'd from the heap

I'm wondering if there's a way to return a value just before it's free'd from the heap.

My problem is that if I do something like this:

queue_item *dequeue(queue *this) {
   node old = this->front;
   this->front = old->link;
   free(old->item);
   free(old);
   return(old->item);
}

Clearly old->item is taken off the heap before it can be returned. Currently to get around this problem, I store the item that was previously used in a field. Then I free that item the next time I dequeue. Finally, I kill the last item in the queue's destructor.

queue_item prev_item;
queue_item *dequeue(queue *this) {
   assert (!queue_isempty (this));
   node old = this->front;
   this->front = old->link;
   queue_item item = old->item;
   free(prev_item);
   prev_item = old->item;
   free(old);
   return(old->item);
}

void queue_destruct(queue this) {
   free(prev_item);
   free(this)
}

But I'm not too happy with this method because I always have an extra item on the heap. Is there a way around this? Is there some sort of elegant solution that I'm missing?

Upvotes: 1

Views: 60

Answers (1)

candied_orange
candied_orange

Reputation: 7334

You should never free it while it's still needed. You should never leave it on the heap once it's not.

What you can do is abstract away the details of how to create it and how to destroy it. But you can't cheat time. You need something that knows when to create and when to destroy it. You need something that knows how to create and how to destroy it. Those two things don't have to be the same thing. One can call the other. But don't request creation with out thinking about when to destroy.

Keep in mind that moving big things around in memory is expensive and often pointless. Keep in mind that you don't dictate where something is allocated, you get told. Once something has been allocated you can share that address. But as the thing, the level, that requested allocation of it, it's YOUR JOB clean up after yourself.

This is something you simply can't do with just one function. You'd need two. One for each moment in time.

If you're at a level where something else asked you to create it you can make it that things job to tell you when to destroy it. It's IN BETWEEN those two moments in time that you can hand up the address and let something above you use it. That something is now responsible for asking you to clean up.

This is what people mean when they say that malloc and free need to be used in pairs. The same can be said of any resource you allocate.

Upvotes: 1

Related Questions