Reputation: 1990
I am getting a strange result in the following C code.
int main()
{
int *p = (int *) malloc(100);
p[120] = 5;
printf("\n %d", p[120]);
}
Since I have allocated only 100 bytes, this code should give cause a segmentation fault. However, it prints '5' and does not give any runtime error. Can anyone please explain the reason?
Upvotes: 6
Views: 9256
Reputation: 19457
No, the code should not (necessarily) give a segfault. A segfault occurs when you attempt to access a virtual memory page that is not allocated to your process.
The "heap" or "free store" is a region of virtual memory pages owned by your process. The malloc()
API sub-divides this region into blocks and returns a pointer to the block.
If you address beyond the end of the block to which you have a pointer, you will usually access memory that is part of the heap, but not part of your allocated block. In this way, you can corrupt other heap blocks or even the data structures which malloc()
uses to define the heap.
For more information on heap corruption, and methods to detect it in the debug version of your code, this is a great book:
Writing Solid Code: Microsoft's Techniques for Developing Bug-Free C Programs by Steve Maguire
An addendum for the pedantic: In rare cases, by accessing memory beyond the end of a heap block, you may access memory that is not part of the heap. In these cases, you may get the segmentation fault you expected. You might also corrupt some other data structure than the heap. It's really a matter of chance. However, the heap itself is very large compared to typical heap blocks, so 99% of the time code such as your example will corrupt the heap. The example you provide falls into that 99% case.
Upvotes: 23
Reputation: 758
Common causes of segmentation fault:
free-ing improper pointers or un-owned blocks.
int *x=0;
x = 200; / causes segmentation fault */
Segfaults are generated by MMU exceptions based on what is determined to be an illegal memory access. Depending on how the OS structures its memory, one memory access on an OS might be legal (although wrong) and on another OS it might be illegal.
Upvotes: 0
Reputation: 44794
No, it can give a segfault, but only if the memory is outside your process. Otherwise it will just modify some other area of your program memory. C doesn't check for this, or protect you in any way, even in obvious cases like the above. Many many software crackers use this "feature" of C to essentially rewrite a program that has elevated privs, and give themselves control over your machine. It is called a buffer overflow exploit.
This is why C (and C++) should really be avoided for new software in preference for safer languages like Ada.
Upvotes: 4
Reputation: 553
You are writing into memory which you have not allocated. The program might eventually terminate due to the effects of heap corruption if its run time were sufficiently long.
Upvotes: 0
Reputation: 39480
You're writing to uninitialized memory; this is allowed in C, it's just not a good idea. This sort of thing shouldn't necessarily cause a segmentation fault.
Upvotes: 1
Reputation: 200746
Invalid memory accesses won't always cause a segmentation fault, bus error, or other crash. For example, if there's another block allocated immediately after your array, you're changing the values in that block -- which could be anything.
Upvotes: 6