-2

I'm learning about memory management in C.

I have a pointer to a struct which I malloc size for via

some_struct *mystruct = malloc(sizeof(some_struct));

and I later use free on that struct.

Inside this struct there are three char * pointers; I malloc their memory as well.

Do I have to free their memory as well before I free *mystruct or will the destruction of *mystruct also free the memory inside the struct?

Alex Feinman
  • 5,393
  • 1
  • 30
  • 48
randy newfield
  • 1,221
  • 3
  • 25
  • 38

4 Answers4

5

You absolutely have to also free the memory pointed to by the char * pointers inside the struct. Do that first, then free your struct

But don't free the char * pointers inside the struct, if you are pointing at the same memory for those char * pointers elsewhere (i.e., if you have copied your struct to another struct instance, those char * pointers need to point to valid memory).

DWright
  • 9,258
  • 4
  • 36
  • 53
  • 1
    C is not a garbage collected language. The runtime does not reference count allocated memory, so that it can figure out when to deallocate things automatically when nothing else refers to them any more. – DWright Dec 23 '12 at 17:39
  • 1
    @DWrigth There isn't even a runtime. –  Dec 23 '12 at 17:40
  • Well, there is a runtime library. – DWright Dec 23 '12 at 17:45
  • 1
    that's called the C standard library. Since C is not a dynamic language, calling the standard library a "runtime" is an error. Take a look at the Objective-C **runtime** library, for example. Now that is a runtime library. –  Dec 23 '12 at 17:50
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/21602/discussion-between-dwright-and-h2co3) – DWright Dec 23 '12 at 17:52
  • hey just a quick question. i create my pointer to my struct like in my post then i pass it to a function with a prototype `void *function(void *param)` from inside the function i call free(param) once i am done making a clone of the structure via `some_struct mynewstruct = *((some_struct *)param);` if i had 3 `char *` variables inside my strut how would i free them from inside the function. `free(param.var);` doesnt seem to work and neitehr does using `->` – randy newfield Dec 23 '12 at 18:00
  • ill take a look at this right now. i also added a extended version of whats happening to the original post along with my error messages from gcc. – randy newfield Dec 23 '12 at 18:15
  • Big caveat, now that I re-read your edits!!! If you copy the contents of the struct via `some_struct mynewstruct = *pParamAsStruct;`, you do NOT need to free the char * pointers when you free *param, in fact to do so would be a bug. – DWright Dec 23 '12 at 18:15
  • Instead, free the char * pointers before you free mynewstruct (Eventually). – DWright Dec 23 '12 at 18:16
3

There's no magic and no Santa Claus. You have to do the work yourself. Free all the memory you allocated dynamically before you lose track of it.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
0

Thats the reason why you later want to change to c++, then you can have a struct which does it by its own (if you put the right code into its destructor). In C you have to do the work by yourself, that is, before deleting your struct, delete the things inside the struct. And, of course, when you malloc a struct, you should also properly initialize the members inside the struct, as minimum initialize pointers to 0, so that there are no glitches when deleting them...

pbhd
  • 4,384
  • 1
  • 20
  • 26
0

As far as good practice goes you should free everything you allocate, think of it like opening an html tag and closing it, and as far as good practices go it's a good idea not to think about structs the way you would about classes in C++ or java.

Freeing structs only free pointers to object, not the object itself,

#include <stdio.h>                                                                                                                                                                   
                                                                                                                                                                               
typedef struct                                                                                                                                                                       
{                                                                                                                                                                                    
    int a,b,c,d;                                                                                                                                                                     
    char some_string[1050];                                                                                                                                                          
                                                                                                                                                                                     
} first_type;                                                                                                                                                                        
typedef struct                                                                                                                                                                       
{                                                                                                                                                                                    
    struct first_type *ap;                                                                                                                                                           
} second_type;                                                                                                                                                                       
                                                                                                                                                                                                                                                                                                                                                                    
int main(void)                                                                                                                                                                       
{                                                                                                                                                                                    
    printf("first type: %d\n", sizeof(first_type));                                                                                                                                  
    printf("second type: %d\n", sizeof(second_type));                                                                                                                                
}          

if you run this little example you will see something like this

first type: 1068

second type: 8

although second_type has a pointer to a first_type it's size is considerably less than first_type. So when you malloc and free stuff you are only reserving and releasing however many bytes that data type is in memory.

Hope this helps.

Community
  • 1
  • 1
Sevki
  • 3,592
  • 4
  • 30
  • 53