Memory Management
In C, you can manually manage memory to have greater control.
If you need to store information on a dynamic number of students, for example, it's wasteful and dangerous to assume a maximum size of e.g. 1000 students. (What if I give you only 50? How about 1001?)
Instead, you can dynamically allocate memory based on your input size, requesting it from the
OS with functions such as
malloc.
Stack and Heap
Local variables are automatically allocated on the stack when they come into scope. They are deallocated (memory is freed) when they exit their scope.
The stack grows from top to bottom.
Manually allocated memory is put on the heap.
The heap grows from bottom to top.
Functions
malloc
void* malloc(size_t size)
Request allocation of size bytes
Returns a void* to the allocated memoru
Returns NULL if allocation failed
free
memset
void* memset(void s[n], int c, size_t n)
Sets first n bytes of memory pointed to by s with byte c.
Returns s (pointer to void)
Can clear memory area given by call to malloc (or use calloc)
calloc
void* calloc(size_t n, size_t size)
Request allocation of n elements of size bytes each
Clears allocated memory with 0
Returns a void* to the allocated memoru
realloc
void* realloc(void* p, size_t size)
Resize memory to size bytes
Doesn't initialize new memory, see memset
If p is NULL → same as malloc(size)
Example
char *p = malloc(sizeof(char * 64));
// char *p = malloc(sizeof(*p * 12)); <<-- *p is a char, same effect as above
// always error check malloc
if (p == NULL) {
fprintf(stderr, "Call to malloc failed! Aborting...\n");
exit(1);
}
// use p
strcpy(p, "malloced string");
puts(p);
// free memory, else memory leak
free(p);