Hi... to avoid dangling pointers, you could define a macro like "#define FREE(ptr) do { free(ptr); ptr = NULL; } while (0)" or "#define FREE(ptr) ({ free(ptr); ptr = NULL; })" and call FREE() instead of free(). Thanks.
Wouldn’t it just be a good idea to manage responsibility better? As in, don’t have a function that processes the array free the memory, but rather, you allocated in main function-let main function be responsible for destruction as well.
Or write constructors and destructors for the memory blocks those pointers point towards. For instance if you have a struct X { int y, int z };, declare a constructor for it that allocates and initalizes the memory which returns a pointer to the newly allocated memory block on success or NULL on failure and also declare a destructor that handles freeing the memory and returns NULL on succes or the original pointer on failure.
It is possible that the second attempt to free a none nulled pointer you won't get an exception and that is WORSE! This is because the first freeing action was successful and in the meantime a second allocation assigns the SAME address to a totally different use. So, the second attempt to free the original blob of memory successfully frees the second blob, without error. The program happily continues until that second blob is accessed and good luck in debugging that exception. So, always NULL a pointer to freed memory, at least until C/C++ gets an erase operator for native types.
I don't do this, but it is because I prefer to be warned when there is a double free in the code. My personal preference is to create wrappers for each data element, and include double free checking in that, since C does not have it. Other languages do.
thanks man, our school teacher only told us that setting a pointer to NULL after freeing is a good practise but not why, so i thought it was just waste of performance.
Ha....recently I've been doing dynamic array and I kept getting my memory overwritten by something. In the end I was told to use realloc and that fixed the issue. Looking back now...when I was resizing the the array I freed but never set the old pointer to NULL. I assumed free() auto invalidates the pointer. Thanks for this video
A similar situation happened to me with a 3D engine I was building. The byproducts of that were very strange and difficult to track down, lost hours of work debugging that. Hence why I mentioned the realloc assignment in the video
Heyy !! i really like your videos so much ! and hope all the best for your channel ! Please , could make a tutorial about the double pointer (the trick that you showed about **arr and how we passed an array into it ... ) Thank you !!!
Thank you for the great explantation of double freeing the same pointer. But, I was thinking that you could just write the process_arr function as below to release the memory allocated on heap in the main: void test(int* ptr){ free(ptr); } And there is no need to send pointer to the arr pointer into the process_arr function. Because the only thing free() method needs is a pointer to the first place of the allocated memory on the heap. However, it is not possible to set the pointer to NULL as we only have a copy of the arr in the function. Am I right?
free() doesn't set anything: int* m = malloc(sizeof(int)); // m has the value 156, being the address where that int is stored free(m); // m will still be 156 here And regarding the NULL aspect. It's just for convenience's sake. An address will never be 0 (0 is the value NULL btw) so it simply ignores it gracefully than bothering the programmers with an error (there might be other historical reasons I don't know about too)
Hi... to avoid dangling pointers, you could define a macro like "#define FREE(ptr) do { free(ptr); ptr = NULL; } while (0)" or "#define FREE(ptr) ({ free(ptr); ptr = NULL; })" and call FREE() instead of free(). Thanks.
That's definitely a nice solution
Why the do/while?
@@sidekick3rida absolutely no point. do {} while(0) used in asserts in case u want to break from assert statement
Wouldn’t it just be a good idea to manage responsibility better? As in, don’t have a function that processes the array free the memory, but rather, you allocated in main function-let main function be responsible for destruction as well.
That's also a good way of managing responsibility
Or write constructors and destructors for the memory blocks those pointers point towards. For instance if you have a struct X { int y, int z };, declare a constructor for it that allocates and initalizes the memory which returns a pointer to the newly allocated memory block on success or NULL on failure and also declare a destructor that handles freeing the memory and returns NULL on succes or the original pointer on failure.
I've been struggling with this recently. That's a really smart way to find issues with double free. I wonder why I haven't thought about it
It is possible that the second attempt to free a none nulled pointer you won't get an exception and that is WORSE! This is because the first freeing action was successful and in the meantime a second allocation assigns the SAME address to a totally different use. So, the second attempt to free the original blob of memory successfully frees the second blob, without error. The program happily continues until that second blob is accessed and good luck in debugging that exception. So, always NULL a pointer to freed memory, at least until C/C++ gets an erase operator for native types.
I don't do this, but it is because I prefer to be warned when there is a double free in the code. My personal preference is to create wrappers for each data element, and include double free checking in that, since C does not have it. Other languages do.
Man, great videos and explanation!!! You have hit the right balance with them. Thanks
thankyou thats gold content!
thanks man, our school teacher only told us that setting a pointer to NULL after freeing is a good practise but not why, so i thought it was just waste of performance.
I really like your videos! Thanks so much for the explanation!!
Ha....recently I've been doing dynamic array and I kept getting my memory overwritten by something. In the end I was told to use realloc and that fixed the issue. Looking back now...when I was resizing the the array I freed but never set the old pointer to NULL. I assumed free() auto invalidates the pointer. Thanks for this video
A similar situation happened to me with a 3D engine I was building. The byproducts of that were very strange and difficult to track down, lost hours of work debugging that. Hence why I mentioned the realloc assignment in the video
love you man thank you so much
Heyy !! i really like your videos so much ! and hope all the best for your channel !
Please , could make a tutorial about the double pointer (the trick that you showed about **arr and how we passed an array into it ... )
Thank you !!!
Thank you! And alright, we'll release a video next week about double pointers.
Sweet. Thanks.
Thank you for the great explantation of double freeing the same pointer. But, I was thinking that you could just write the process_arr function as below to release the memory allocated on heap in the main:
void test(int* ptr){
free(ptr);
}
And there is no need to send pointer to the arr pointer into the process_arr function. Because the only thing free() method needs is a pointer to the first place of the allocated memory on the heap. However, it is not possible to set the pointer to NULL as we only have a copy of the arr in the function. Am I right?
Yes, you can no longer set that arr pointer (defined in main) to NULL if you only pass a simple pointer
Sergiu. Does free() set the ptr to NULL? How is it that it does nothing if the ptr is NULL? Is it maybe because a NULL ptr is already freed?
free() doesn't set anything:
int* m = malloc(sizeof(int)); // m has the value 156, being the address where that int is stored
free(m);
// m will still be 156 here
And regarding the NULL aspect. It's just for convenience's sake. An address will never be 0 (0 is the value NULL btw) so it simply ignores it gracefully than bothering the programmers with an error (there might be other historical reasons I don't know about too)
When you write in the function *arr = NULL; in the main arr is now contained in the stack,isn’t it?
arr is ALWAYS contained in the stack of the main function. *arr (the address at which arr is pointing towards) was dynamically allocated
@@CodeVault Thank you👍
i have one question ,in terms to not get double free it wouldnt be better to do every time we free this:
if(arr!=NULL){
free(*arr) ;
arr=NULL;
}
?
Yes, that would be a good solution
Why doesn't the compiler check this?
The C compiler (and language) is very simple. It gives you more control but you have to be more careful