I am relatively new to C programming and having a hard time understanding the whole memory allocation issue.
Let’s say, I do:
int *n = malloc(sizeof(char));
// (assuming malloc doesn't return NULL of course)
That provides a Pointer to int, but I didn’t allocate enough memory for an int. Why does it work then? I could even cast it to int explicitly and it wouldn’t bother gcc. I am aware of C compilers being very minimalist, but even if I assign a value to *n, which doesn’t fit in a char, like:
*n = 300;
… and print it out afterwards:
printf("%d", *n);
… it works perfectly fine, although now at the latest I’d expect some error like a segmentation fault.
I mean, sizeof(char) is 1 and sizeof(int) is 4 on my machine. Hence 3 bytes are written to some place in memory which hasn’t been allocated properly.
Does it work just because it doesn’t leave the stack?
Could somebody please point me to a place where I might find enlightenment concerning that stuff?
The return value from malloc is
void*, the language allows this to be implicitly converted to any pointer type, in this caseint*. Compilers don’t typically include behavior to check that what you passed tomallocmet a specific size requirement, in real-world code that can be very difficult (when non-constant sizes not known at compile time are passed to malloc). As you said, C compiler are usually rather minimalist. There are such things as “static analysis” tools which can analyze code to try to find these bugs, but that’s a whole different class of tool than a compiler.Writing beyond the bounds of allocated memory is what is called “undefined behavior”. That means that a compliant compiler can do whatever it wants when that happens. Sometimes it will crash, sometimes it can write over some other variable in your program, sometimes nothing will happen, and sometimes nothing will seem to happen and your program will crash at a later date.
In this particular case what is happening is that most implementations of
mallocallocate a minimum of 16 bytes (or more or less, like 8 or 32) even if you ask for less. So when you overwrite your single allocated byte you’re writing into “extra” memory that was not used for anything. It is highly not recommended that you rely on that behavior in any real program.The stack has nothing to do with this particular situation.
Any good C book will have information of this type, take a look here: The Definitive C Book Guide and List