C Language Dynamic Memory Flashcards
Think about why we returned a pointer to the newly created array instead of creating a local array inside the function create_array() and returning that array instead. How is stack memory different from heap memory?
Since local variables are stored on the stack, while we could return a pointer to one of them, we cannot rely on that memory to still be allocated once the function returns and the stack frame is popped from the stack. However, heap memory is accessible if we have a pointer to it. The programmer can manage the life time of the heap memory by calling malloc() (allocating memory) or free() (deallocating memory) unlike the stack memory.
Dynamic
means “at run-time” (not “at compile-time”);
compiler does not have enough information to make final decision. Unlike atomic or static memory allocation e.g. int a = 0
size_t
a typedef type for an unsigned int
void* malloc(size_t size)
returns a pointer to a region on the heap of size bytes. If successful, space is contiguous. If heap can’t fulfill request, returns NULL.
Think of it as creating a reservation for a region of memory that only you
can write to, until you call: free() and release that reservation.
void free(void* ptr)
clears reservation for address pointed to be ptr and for all the rows initially reserved by the corresponding call to malloc( ). Example: you ask malloc for 6 rows. When you call free, it will release the reservation on those
6 rows.
You have to call it as many times as you call malloc, to the same pointer malloc returned and in the right order
sizeof( )
an operator (not a function) in C that will compute the size of its operand in bytes. Works on any data type, even structs. Note: sizeof() may give different output according to machine
Memory leak
memory on heap you no longer have a reference to. Example: int* my_pointer = malloc(4). my_pointer is a reference to the memory you have reserved. But if you then alter it: my_pointer = NULL, you have lost the only
reference you had to your reservation on the heap. Now you can never return to
that region or even release it using free( ).
Linked list
a type of data structure itself, the purpose of which is to “link” groups of data together. We call the “groups” nodes in the context of a linked list.
struct Node { int data; struct Node* next; };
struct Node node1;
node1. data = 1;
node1. next = NULL;
struct Node node2;
node2. data = 2;
node2. next = NULL;
node1. next = node2;
Make “struct Node* curr “ point first to node1 and then next of node 1
//Pointer to a node struct Node* curr = &node1; //next returns pointer to Node curr = curr->next;
Declaration
when you describe something to the compiler but don’t actually ask for space for it. Don’t instantiate it.
Function no curly brackets
vs. Definition, when you instantiate something
Steps for malloc( ):
○ char *str; ○ str = (char *) malloc(10); // better: str = (char*)malloc(10*sizeof(char)); // check that molloc did not return NULL ○ strcpy(str, "OMCIT593");
Steps for free( )
Remember: each call to malloc( ) requires a corresponding call to free( )
Advantages of linked lists:
○ Growth of the list can be dynamic (occur while the programming is running)
○ More efficient use of memory
○ Shrinking/reordering our list can also be dynamic
Disadvantages of linked lists:
○ Pointer and memory management are tricky
○ More difficult to find things i.e. “traverse the list”
Memory leaks - Most common causes
■ You were done with memory you had allocated…
■ Then you overwrote the last pointer that pointed to it…
■ BUT you forgot to call free( ) on it first!
○ Block is gone (cannot be reallocated) for duration of program.
○ If you do this repeatedly, your program won’t have heap anymore!
Garbage collection:
○ Helps avoid leaks while saving you from having to call free( )
○ “Reclaims” everything in heap region that is not pointed to
○ C does not have this (but Java does)
“Buffer overflows”
○ Example: ask for 10 bytes but write 11
○ Bad to do in general but especially bad in the heap
○ C does not check for this (but Java does)
Remember to check the return value of malloc( )
○ malloc( ) is allowed to return NULL (out of memory)
○ Should check for NULL after every call to malloc( )
Passing a pointer to the middle of allocated region to free( ) - issue
○ free( ) won’t be able to find the block
why is lengthof() array not possible
Array only passed with address in function calls.
sizeof works as pointers must by typed and we can infer the size of array
However we cannot infer the number of elements in that array
Heap
Region in data memory set aside for variables whose size we don’t know until program is running.
Use malloc to ask for space
What happens with
int length = 2 ;
int int_array [length]
compile error.
Data i.e. the length = 2 is not commited to the stack until program is running. as we are asking for user to specify length. Hence, compiler does not know how large the int array shall be
Stack and Global Region vs heap
Static, global: known at compile time
heap: accessible at runtime
return type of malloc
void*
Hence need always to cast it
What will happen to ptr after: free(ptr)
ptr on stack will still refer to the address in malloc. However you cannot access the data there anymore. The reservation/table has been released
heap memory lasts until you free it.
It is freed for someone else to overwrite it, as long as this does not happen, data still there
What is wrong
#include typedef struct cust_struct { int id ; char* name ; } customer ;
int main () { customer my_cust ; my_cust.id = 1234 ; strcpy (my_cust.name, “Tom”) ; return 0 ; }
strcpy (my_cust.name, “Tom”) ; does not work
name is a pointer that is pointing to nothing as it has never been initialized. i.e. my_cust.name = NULL
if name would be defined e.g. as char name[4] it would work, because “name” would have space allocated