Take the following code :
int *p = malloc(2 * sizeof *p);
p[0] = 10; //Using the two spaces I
p[1] = 20; //allocated with malloc before.
p[2] = 30; //Using another space that I didn't allocate for.
printf("%d", *(p+1)); //Correctly prints 20
printf("%d", *(p+2)); //Also, correctly prints 30
//although I didn't allocate space for it
With the line malloc(2 * sizeof *p)
I am allocating space for two integers, right ? But if I add an int
to the third position, I still gets allocated correctly and retrievable.
So my question is, why do you specify a size when you use malloc
?
The sizeof command in C returns the size, in bytes, of any type. The code could just as easily have said malloc(4), since sizeof(int) equals 4 bytes on most machines. Using sizeof, however, makes the code much more portable and readable. The malloc function returns a pointer to the allocated block.
The result of calling malloc(0) to allocate 0 bytes is implementation-defined. In this example, a dynamic array of integers is allocated to store size elements. However, if size is 0, the call to malloc(size) may return a reference to a block of memory of size 0 instead of a null pointer.
There are lots of ways in which malloc/free can store the size of the memory area. For example, it might be stored just before the area returned by malloc. Or it might be stored in a lookup table elsewhere. Or it might be stored implicitly: some areas might be reserved for specific sizes of allocations.
malloc(0) does not allocate any memory. [EDITED: it can sometimes allocate memory, see my next answer] The return value of malloc (0) is implementation specific: it can return NULL or a valid pointer (some unique value) as in your case but memory is not allocated!!!
Simple logic: If you do not park in a legal parking space, nothing might happen but occasionally your car might get towed and you might get stuck with a huge fine. And, sometimes, as you try to find your way to the pound where your car was towed, you might get run over by a truck.
malloc
gives you as many legal parking spots as you asked. You can try to park elsewhere, it might seem to work, but sometimes it won't.
For questions such as this, the Memory Allocation section of the C FAQ is a useful reference to consult. See 7.3b.
On a related (humorous) note, see also a list of bloopers by ART.
C kindly let you shoot yourself in the head. You have just used random memory on the heap. With unforeseeable consequences.
Disclaimer: My last real C programing was done some 15 years ago.
Let me give you an analogy to why this "works".
Let's assume you need to draw a drawing, so you retrieve a piece of paper, lay it flat on your table, and start drawing.
Unfortunately, the paper isn't big enough, but you, not caring, or not noticing, just continue to draw your drawing.
When done, you take a step back, and look at your drawing, and it looks good, exactly as you meant it to be, and exactly the way you drew it.
Until someone comes along and picks up their piece of paper that they left on the table before you got to it.
Now there's a piece of the drawing missing. The piece you drew on that other person's paper.
Additionally, that person now has pieces of your drawing on his paper, probably messing with whatever he wanted to have on the paper instead.
So while your memory usage might appear to work, it only does so because your program finishes. Leave such a bug in a program that runs for a while and I can guarantee you that you get odd results, crashes and whatnot.
C is built like a chainsaw on steroids. There's almost nothing you cannot do. This also means that you need to know what you're doing, otherwise you'll saw right through the tree and into your foot before you know it.
You got (un)lucky. Accessing p[3] is undefined, since you haven't allocated that memory for yourself. Reading/writing off the end of an array is one of the ways that C programs can crash in mysterious ways.
For example, this might change some value in some other variable that was allocated via malloc. That means it might crash later, and it'll be very hard to find the piece of (unrelated) code that overwrote your data.
Worse yet, you might overwrite some other data and might not notice. Imagine this accidentally overwrites the amount of money you owe someone ;-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With