Thanks for the video! A sidenote: I believe returning a pointer to a heap allocated memory "is not" a good practice , as it makes the caller of function responsible for freeing the memory allocated by the callee. I guess we should pass the adress of the pointer to the heap allocated memory in the caller function, to the callee: ``` void remove_duplicates(int array[], int length, int **new_array, int *new_length); ~~~ int *after = malloc(10 * sizeof(10)) int after_length = 0 remove_duplicates(test, 10, &after, &after_length) ``` In function definition we can use things like following: ``` (*after)[unique_count] = ... ~~~ *after = realloc(...) ``` Please let me know if I'm missing something.
@PortfolioCourses2 жыл бұрын
I've never heard of that before, the idea that it's not a good practice for a function to return a pointer to dynamically allocated memory. I do not believe that is true. Libraries like direct.h work this way: github.com/portfoliocourses/c-example-code/blob/main/_getcwd.c. And libraries for data structures and related algorithms tend to work this way. I don't see how we would do it any other way either... we can't make the function responsible for free-ing the data because once it is done executing it is done executing. We can't split up our program into functions AND have the functions responsible for free-ing the memory they allocate. What you've done doesn't really change anything fundamentally, it's just passing the memory address (pointer) of the dynamically allocated memory back to the main function using pass-by-pointer instead of returning it directly. But there is nothing bad or fundamentally different about returning it directly from the function. Remember that in the remove_duplicates() function malloc() and realloc() are going to allocate space in memory for "our program to use". It doesn't matter where the space is allocated in terms of the function, all that matters is that some block of memory has been set aside for our program to use. And in the case of both malloc() and realloc() we are given a memory address (i.e. pointer) for that space in return. When we return that pointer from our remove_duplicates function, all we're doing is just returning that same memory address (pointer). We could do it with pass-by-pointer, but there wouldn't be any advantage in doing so.
@reverseila2 жыл бұрын
@@PortfolioCourses What I'm trying to say is: Imagine you are writing a library. Why should the user of your library free the memory you allocate. Isn't it a bad thing? Or it's just a normal thing in C? (Please excuse me as I'm just a beginner) In the case of what I suggested, yes I'm using realloc.but aside from that user should do the allocation. It's more error prone to track which function allocates memory, and which one don't. It's just matter of possibility of forgetting to free. If I didn't malloc memory, I shouldn't be responsible to free it.
@PortfolioCourses2 жыл бұрын
@@reverseila It's just a normal thing in C. In C we have manual memory management where it's a normal expectation that the programmer has to free memory that has been allocated, even memory that has been allocated by a library (the library documentation should make it clear when memory has been allocated). Sometimes libraries will have methods that you call in sequence, or with some sort of order to them, and a later function in the sequence may free memory that was allocated by functions earlier in the sequence. That's about what can be done in terms of "not having the user of the library free memory", but even then if they don't call the functions in the right sequence of forget one, we'll have a memory leak. This is something inherent to C. Languages like Python and Java have what's called a garbage collector that automates this for us so we don't need to manually manage memory. I much prefer this approach as manual memory management leads to mistakes in practice, even when programmers are aware of the issues and diligent mistakes can happen. 🙂
@reverseila2 жыл бұрын
@@PortfolioCourses Now I C :) Thanks for your explanation!