[Univ of Cambridge] [Dept of Engineering]
next up previous contents
Next: Find the bug Up: Some Common mistakes Previous: declaration mismatch

malloc

``Shipping C code has, on average, one bug per 55 lines of code. About half of these bugs are related to memory allocation and deallocation.'' - (anonymous but believable). malloc() allocates memory dynamically. The standard malloc() and free() functions need to be efficient and can't check the integrity of the heap on every call. Therefore, if the heap gets corrupted, seemingly random behaviour can occur. The following code won't work.

          char *answer;
          printf("Type something:\n");
          gets(answer);
          printf("You typed \"%s\"\n", answer);
The pointer variable answer, which is handed to the gets function as the location into which the response should be stored, has not been set to point to any valid storage. That is, we cannot say where the pointer answer points. Since local variables are not initialized, and typically contain garbage, it is not even guaranteed that answer starts out as a null pointer.

The simplest way to correct the question-asking program is to use a local array, instead of a pointer, and let the compiler worry about allocation:

          #include <string.h>

          char answer[100], *p;
          main(){
            printf("Type something:\n");
            fgets(answer, 100, stdin);
            if((p = strchr(answer, '\n')) != NULL)
                  *p = '\0';
            printf("You typed \"%s\"\n", answer);
          }
Note that this example also uses fgets instead of gets (always a good idea), so that the size of the array can be specified and fgets will not overwrite the end of the array if the user types an overly-long line, though unfortunately for this example, fgets does not automatically delete the trailing \n, as gets would.

Alignment problems can arise if malloc is used carelessly. Processors have different rules about (for instance) whether a long can be stored starting at an odd memory location. If you try to break these rules, your program will crash giving little or no clue why. The HP RISC chips only permit a double to start at an address divisible by 8, so trying something like

char *block = (char*) malloc(sizeof(double));
double d = 1.2;
     * (double*)block = d;
is likely to crash.


next up previous contents
Next: Find the bug Up: Some Common mistakes Previous: declaration mismatch
Tim Love
1999-10-06