Why C is NOT a memory safe language.

When you become more experienced in C programming you eventually hit pointers, and the memory problems associated with them. Well, let’s face it, the minute you start dealing with arrays and strings in C there is a chance of something going awry. Consider the following piece of code:

#include <stdio.h>
#include <string.h>

void buffer_overflow(char *str)
{
    char buffer[10];
    strcpy(buffer, str);
}

int main (void)
{
    char *str = "Do or do not, there is no try";
    // length of str = 30 bytes
    buffer_overflow(str);
    return 0;
}

When this code is compiled (with gcc) and executed on OSX: it fails, returning “Abort trap: 6“.  This implies that the program failed due to a SIGABRT signal, in this case #6. Why did it fail – well, likely because of the buffer overflow that occurred when an attempt was made to copy the contents of the string str into the string buffer – that latter only has enough room for 9 characters, and hence the program fails. The program compiled in a similar manner on a Raspberry Pi running Linux (gcc V.4.5.1) will produce the ubiquitous “segmentation fault”.

Another problem is the  dangling pointer, which points to memory that has already been freed, i.e. the storage is no longer allocated. Consider the following piece of code:

char* faulty_string()
{
    char str[20];
    strcpy(str,"Fawlty Towers");
    return(str);
}

int main (void)
{
    char *str;
    str = faulty_string();
    printf("%s", str);
    return 0;
}

The function faulty_string does not work as expected because the string being returned is a local variable. The programs behaviour at this point is somewhat undefined. In this case it printed “� “, but it could just have easily crashed. The code would have worked had str been a dynamic array. Thankfully, most compilers provide some form of warning that this is happening, usually in a message of the form: “warning: function returns address of local variable” (even without the use of -Wall in gcc). Another form of dangling pointer is when a memory location is accessed after it has been freed. A good example of this is:

int *aNumber = malloc(sizeof(int));
free(aNumber);
*aNumber = 12;
printf("%d", *aNumber);

And when compiled, this code *actually* runs with no issues, printing the value 12. Alternatively one could also experience a memory leak, which signifies heap memory which has not been freed, but is now out of scope, so there is no way to access the memory – basically orphaned memory. A good example is shown in the code below:

void memory_leak()
{
    char *str;
    str = (char*) malloc(100);
    // ...
}

As the string str can not be accessed outside the function memory_leak, the 100 bytes is essentially lost. Too many memory leaks, and the system itself will start to show problems.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s