0

I have a linked list of structures and would like to delete and return the element (a struct) from the first position of the linked list.

Now, it's good practice to free the memory location previously occupied by the node so I am not sure if my only option to return the deleted node is creating a malloced deep copy before deleting it and returning that copy?

Item *deleteFromStack(stack *s) {
    if (s == NULL) return NULL;
    Item *first = getFirst(s->list);
    deleteFirst(q->list); // PROBLEM HERE: deleteFirst will free the memory pointed by first 
    return first; // now first has garbage values
}
  • 1
    The function should not return a node. The node is the internal implementation of the list. The function should return the data stored in the node. – Vlad from Moscow Feb 09 '22 at 21:11
  • @VladfromMoscow Sorry, I meant that. The data of my node is a struct. I will update my question. –  Feb 09 '22 at 21:12
  • Updated my question. –  Feb 09 '22 at 21:13
  • It's still not entirely clear. Please show actual code as a [mre]. – kaylum Feb 09 '22 at 21:13
  • Why would you make a copy rather than just return the element directly? If you are transferring ownership of data there is no need to free it. But I suspect your data structure may not be well set up to do that. Details matter. That's why we need to see your code. – kaylum Feb 09 '22 at 21:16
  • @kaylum updated with a MRE. –  Feb 09 '22 at 21:18
  • That's is not a *complete* code example. What is `stack`? What does `deleteFirst` look like exactly? – kaylum Feb 09 '22 at 21:18
  • @kaylum I don't think the other details matter. I have implemented a stack backed by a linked list. –  Feb 09 '22 at 21:19
  • A common option is to have a "remove" or "pop" that unlinks the node but does not free the element. – kaylum Feb 09 '22 at 21:19
  • @kaylum That was my first thought too..but wouldn't that waste memory? –  Feb 09 '22 at 21:20
  • 1
    What do you mean waste memory? The ownership is being transferred to the caller who is then responsible for freeing it. If you take a candy out of your bag and give it to someone would you destroy the candy first because you want to dispose of the wrapper? No, you would give the whole candy to the other person and leave them to dispose when no longer needed. – kaylum Feb 09 '22 at 21:20
  • @kaylum Oh, that makes sense. I had presumed that the client shouldn't bother about memory management for the data structure. –  Feb 09 '22 at 21:22
  • 1
    @GoldCredential If the client is going to get an object back, it has to be responsible for freeing that object when it's done with it. An object can't be freed until it is no longer needed, so whatever code is going to be the last code to need the object has to free it. – David Schwartz Feb 09 '22 at 21:31
  • That makes sense, thank you @DavidSchwartz. –  Feb 09 '22 at 21:37
  • Don't return a pointer to `Item` - just return `Item` by value. Assign `Item first = getFirst(s->list);` and then return `first` and there is no problem with deleting the node and the caller doesn't have to free the object either. You will need to change the function to `Item deleteFromStack(stack *s)` to make that . – Jerry Jeremiah Feb 09 '22 at 22:10
  • @JerryJeremiah What if Item were a "heavy" struct? Wouldn't it be bad to pass around such a large block of memory? –  Feb 14 '22 at 19:26
  • If you return a struct by value and the function return value is assigned to a variable, a good compiler should put the value directly into that variable without a copy - and as of C++17, copy elision is guaranteed when an object is returned directly: See https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization – Jerry Jeremiah Feb 14 '22 at 20:18

0 Answers0