/** * Variables must be explicitly allocated and * explicitly freed. All dereference must be * explicit. * If you want to allocate memory inside a function and return * it to the calling function, then you need to allocate that memory * on the heap (malloc!). */ #include #include int* createThingBadly( ) { int thing = 10; return &thing; // Don't do this!!! The memory that was allocated on the call stack will be gone. } // Demonstrate that if we have a pointer to a pointer // We need to malloc and free both. typedef struct { int *items; int num_items; } Container; // This allocates a container for num_items ints // It returns a pointer to the allocated container Container *make_container( int num_items ) { Container *c; c = (Container *)malloc(sizeof(Container)); c->items = (int*)malloc(sizeof(int)*num_items); c->num_items = num_items; for (int i = 0; i < num_items; i++) { c->items[i] = i+1; } } // This frees the data in the container and the // container itself void destroy_container( Container *c ) { free( c -> items ); free( c ); } // test code for container void test_container() { Container *c = make_container( 5 ); //free( c ); destroy_container( c ); } int main (int argc, char* arvg[]) { int *a = (int *)malloc(sizeof(int)); printf( "%d\n", a == NULL ); // shouldn't check value if it hasn't been assigned a value. *a = 4; printf( "a has a value that is an address: %p\n", a ); printf( "*a =%d\n", *a ); free(a); printf( "a has a value that is an address: %p\n", a ); printf( "*a =%d\n", *a ); // illegal but runs! int* thg = createThingBadly(); printf( "thing is %d\n", *thg ); // a = NULL; // printf( "*a =%d\n", *a ); // crashes return 0; }