Why doesn't running this lead to a segmentation error?

Possible duplicate:
An incorrect read / write sometimes creates a segmentation error, and sometimes does not work

I have the following code:

#include <stdlib.h> #include <stdio.h> int main() { int *ptr = NULL; ptr = malloc(sizeof(char)); if (ptr) { *ptr = 10; printf("sizeof(int): %zu\nsizeof(char): %zu\n", sizeof(int), sizeof(char)); printf("deref of ptr: %d\n", *ptr); free(ptr); return EXIT_SUCCESS; } else return EXIT_FAILURE; } 

When I compile and run it, I get the following output:

 $ gcc test.c $ ./a.out sizeof(int): 4 sizeof(char): 1 deref of ptr: 10 

sizeof(char) less than sizeof(int) . My call to malloc allocates enough space for char . However, my program can assign an integer ptr value without crashing. Why does it work?

+4
source share
5 answers

Just because you write to unallocated memory does not mean that the program will fail. There are no runtime checks.

Segfault will occur when you access memory from the address range allocated by the operating system as detected by the hardware. You can leave with more memory access before on your heap.

+8
source

Writing to too small a buffer is undefined behavior. There is no guarantee that he will crash. It may not end. Maybe it works. This may damage some data. This can lead to the fact that your program will do something unintentionally - because of this, many security holes arise when an attacker manipulates the effect of undefined behavior into something undesirable. Thanks to a rigorous reading of the standard, this can even trigger the calling of demons from your nose.

At the architecture level, distributions are usually rounded to some extent by two (but this is not guaranteed by any means!), So why didn’t you see anything obvious here. But do not rely on this, as it can and does change.

+6
source

malloc implementation can and will often allocate a bit more memory than you requested. Most implementations will be rounded to the nearest multiple of 8 or 16 bytes, at least.

+4
source

Hardware memory managers manage full pages of memory, often 4K. If your record does not overflow the page boundary, the memory management hardware will not generate a SEGFAULT / Access Violation interrupt.

Your example “works” because one element of the large set of “undefined behavior” is working correctly, at least for now. ”If you add complexity to your application, other members of the set will appear ...

+2
source

This works by accident. Your malloc will most likely highlight a chunk significantly larger than one character (usually because tracking nanoscopic details is not worth the overhead). That way, you are probably tromping outside the space you should have, but that doesn't matter in your implementation.

Your program is still erroneous, I think, in accordance with the standard. And if it was a lot more, and you made this mistake in places where it did not work by chance, you will get all kinds of bad behavior, sometimes illegal access to memory, but sometimes just completely crazy behavior, because you can damage your own or system data structures.

Our CheckPointer tool should recognize this error; technically, you save outside the requested area and discover it with sufficient effort.

+1
source

Source: https://habr.com/ru/post/1388850/


All Articles