Search code examples
cmallocstrcpynul

malloc and strcpy interactions


I've been testing out interactions between malloc() and various string functions in order to try to learn more about how pointers and memory work in C, but I'm a bit confused about the following interactions.

char *myString = malloc(5); // enough space for 5 characters (no '\0')
strcpy(myString, "Hello"); // shouldn't work since there isn't enough heap memory
printf(%s, %zd\n", myString, strlen(myString)); // also shouldn't work without '\0'
free(myString);

Everything above appears to work properly. I've tried using printf() for each character to see if the null terminator is present, but '\0' appears to just print as a blank space anyways.

My confusion lies in:

  • String literals will always have an implicit null terminator.
  • strcpy should copy over the null terminator onto myString, but there isn't enough allocated heap memory
  • printf/strlen shouldn't work unless myString has a terminator

Since myString apparently has a null terminator, where is it? Did it just get placed at a random memory location? Is the above code an error waiting to happen?


Solution

  • Addressing your three points:

    • String literals will always have an implicit null terminator.

    Correct.

    • strcpy should copy over the null terminator onto myString, but there isn't enough allocated heap memory

    strcpy has no way of knowing how large the destination buffer is, and will happily write past the end of it (overwritting whatever is after the buffer in memory. For information on this off-the-end-access look up 'buffer overrun' or 'buffer overflow'. These are common security weaknesses). For a safer version, use strncpy which takes the length of the destination buffer as an argument so as not to write past the end of it.

    • printf/strlen shouldn't work unless myString has a terminator

    The phrase 'shouldn't work' is a bit vague here. printf/strlen/etc will continue reading through memory until a null terminator is found, which could be immediately after the string or could be thousands of bytes away (in your case you have written the null terminator to the memory immediately after myString so printf/strlen/etc will stop there).

    Lastly:

    • Is the above code an error waiting to happen?

    Yes. You are overwriting memory that has not been allocated which could cause any manor of problems depending on what happened to be overwritten. From the strcpy man page:

    If the destination string of a strcpy() is not large enough, then anything might happen. Overflowing fixed-length string buffers is a favorite cracker technique for taking complete control of the machine. Any time a program reads or copies data into a buffer, the program first needs to check that there's enough space. This may be unnecessary if you can show that overflow is impossible, but be careful: programs can get changed over time, in ways that may make the impossible possible.