Memory Management in C

25 February 2020

Obed N Munoz

Cloud Software Engineer

Memory Structure

2

Dynamic Memory Allocation

The process of allocating memory space at run time.

C offers a set of functions for dynamic memory allocation. Below some of the most common ones:

- malloc    // allocates size bytes of memory and returns a pointer to the allocated memory
- realloc   // tries to change the size of the allocation pointed to by ptr to size
- calloc    // allocates the specified number of bytes and initializes them to zero
- free      // releases the specified block of memory back to the system
3

Pointers, behind the scenes

Let's say:

char *p; // 4 consecutive bytes in memory for the p variable

Case 1:

char *p = NULL;
strcpy(p, “Hello”);
// Result
Segmentation Fault. Worse yet, the copy may actually succeed.

Trying to copy the string "Hello" into location 0 (NULL) results in a run-time Bus Error and a program crash.

4

Properly allocating memory

We can use malloc or calloc to request a pointer to a block of memory

void *malloc(size_t byteSize)
void *calloc(size_t numElems, size_t byteSize)
int main() {
    char *q = NULL;

    printf("Requesting space for \"Goodbye\"\n");
    q = (char *)malloc(strlen("Goodbye")+1);
    printf("About to copy \"Goodbye\" to q at address %u\n", q);
    strcpy(q, "Goodbye");
    printf("String copied\n");
    printf("%s\n", q);

    return 0;

}
5

Successful allocation?

#include <stdio.h>
#include <stdlib.h>

int main() {

    char *q = NULL;

    printf("Requesting space for \"Goodbye\"\n");
    q = (char *)malloc(strlen("Goodbye")+1);

    // Proper allocate validation
    if (!q) {
    perror("Failed to allocate space because");
    exit(1);
    }

    printf("About to copy \"Goodbye\" to q at address %u\n", q);
    strcpy(q, "Goodbye");
    printf("String copied\n");
    printf("%s\n", q);
}
6

Done, let's free the space

Local variables are destroyed when their enclosing function terminates.

#include <stdio.h>

char *foo(char *p) {
    char q[strlen(p)+1];
    strcpy(q, p);
    printf("From q: the string is %s\n", q);
    return q;
}

int main() {
    char *a = NULL;
    char *b = NULL;

    a = foo("Hi there, Chris");
    b = foo("Goodbye");
    printf("From main: %s %s\n", a, b);
    return 0;
}
7

The address of q is returned to main, where there is an attempt to preserve and use the strings. The result is disastrous.

int main() {
    char *a = NULL;
    char *b = NULL;

    a = foo("Hi there, Chris");
    b = foo("Goodbye");
    printf("From main: %s %s\n", a, b);
    return 0;
}
char *foo(char *p) {
    char *q = (char *)malloc(strlen(p)+1);
    strcpy(q, p);
    printf("From foo: the string is %s\n", q);
    return q;
}
From foo: the string is Hi there, Chris
From foo: the string is Goodbye
From main: Hi there, Chris Goodbye
8

The correct way to release the space is to use free().

int main() {
    char *a = NULL;
    char *b = NULL;

    a = foo("Hi there, Chris");
    free(a);
    b = foo("Goodbye");
    free(b);
    printf("From main: %s %s\n", a, b);
    return 0;
}
char *foo(char *p) {
    char *q = (char *)malloc(strlen(p)+1);
    strcpy(q, p);
    printf("From foo: the string is %s\n", q);
    return q;
}
From foo: the string is Hi there, Chris
From foo: the string is Goodbye
From main: Goodbye Goodbye
9

Resources and Credits

This material is genereated thanks to some extracts from following resources:

10

Thank you

Obed N Munoz

Cloud Software Engineer

Use the left and right arrow keys or click the left and right edges of the page to navigate between slides.
(Press 'H' or navigate to hide this message.)