Reputation: 16730
As far as I understand, a segfault is raised whenever a program attempts to access unauthorized memory.
The following code allocates a one-int memory block to p
, and then tries to write at some unknown address.
#include <stdlib.h>
int main(void)
{
int* p = malloc(sizeof(int));
p[1000] = 12;
return 0;
}
Why does this code raise no segmentation fault, while it tries to access this somewhat random address?
Related
How undefined is undefined behavior? - Explains undefined behaviours, but not why that p[1000] = 12
instruction does not raise a segfault.
Upvotes: 1
Views: 787
Reputation: 213746
The following code allocates a one-int memory block to p, and then tries to write at some unknown address.
It's not an "unknown" address; the address is p+4000
on a system with sizeof(int) == 4
.
Most current operating systems use demand paging. On such a system, the very first call to malloc
is likely to allocate a fresh page of memory. Common page size is 4096
, and writing anywhere within this (writable) page will not produce a segmentation fault.
This program on the other hand very likely will produce a segmentation fault:
int main(void)
{
int* p = malloc(sizeof(int));
int j;
for (j = 1000; j < 100000; j++) p[j] = 12;
return 0;
}
Upvotes: 2
Reputation: 1763
As far as I understand, a segfault is raised whenever a program attempts to access unauthorized memory.
Segfault raised when you're trying to access non paged memory block, there is nothing with authorization.
So does p[1000] points to non paged area? its undefined, however in your case, each dynamic memory allocation needs to be allocated in a memory page which is usually 4096 bytes in x86 systems, when youre calling malloc, it searches for free space in allocated pages, if no suitable memory block found (in previously allocated pages or freed ones), a new page request will be placed and a memory page will be allocated. now the malloc reserves the a portion of allocated page for you (if the size requested + headers are smaller than page size) and return the pointer of it.
Now when you're trying to access p[1000] you're actually accessing non reserved (not malloced) area, but the area is paged (remaining of previous allocation) so no segfault will be raised, but if you try access to bigger index like p[10000] probably you will get segfault.
There are more examples here
Upvotes: 0
Reputation: 1836
When you start your program, OS will divide the programs memory into readable (code section) and writable (data section as well as heap). Now it will depend on the address stored in the pointer you are d-referencing.
If it points to a valid writable memory then no segmentation fault exception will be raised, otherwise a segmentation fault exception will be raised.
Upvotes: 1
Reputation: 13954
By doing p[1000] = 12;
, you are simply putting a value at the address (p+1000)
. There is nothing that should result into segfault. The address could be a valid one, though not legitimately acquired by p
.
Upvotes: 1
Reputation: 16417
It all depends on what platform and what operating system you are running this on. If you compile this code and run it on a processor that does not have an MMU or MPU, then you will not get any exception / segmentation fault.
Upvotes: 0