Why is more memory allocated to a local variable on the stack than is required in C ++?

I read about buffer overflows. I discovered one strange thing about allocating memory to a local variable on the stack

int f1 () { char string1[12]; char string2[4]; } 

Here the distribution takes place on the stack.

Now in GCC line2, 4 bytes are allocated, but if I declare, besides force 2 (up to 16), then it is allocated 16 bytes by the compiler. This means that if I allocate string2 to 3,5,6,7, ...., 15 bytes, then it allocates 16 bytes to the compiler, but if I allocate 2 in strength, like 1,2,4,8 .. . then it stands out exactly the same size. If I assign above 16 bytes (not power 2) then it allocates 32 bytes (I think up to 32 bytes).

While in Visual Studio, if I allocate 1 byte, then 9 bytes are allocated, if 12 bytes are allocated from 2-4 bytes, then 16 bytes are allocated from 5-8 bytes by the compiler.

Does anyone know why such an appointment?

Atleast In Visual studio, if there is a buffer overflow, I get a debugging error, but nothing happens in gcc. GCC provides only a segmentation error only if too much overflow occurs.

+6
source share
3 answers

The sizes of the stack frames affect the choice of memory alignment, as a rule, a multiple of 4 for 32-bit code and a multiple of 8 for 64-bit code.

Both compilers can include checking the frame frame of the canary stack, an additional 32-bit value at the top of the stack, which is initialized when the function is entered and checked when the function exits. If the canary value has changed, the program is interrupted because the stack frame may be corrupted, possibly by malicious code that can change the return address of the function and force it to return to an arbitrary place. A very popular malware injection vector.

MSVC has the / RTC option enabled by default in the Debug configuration. What adds these canaries between each local variable. In this way, it can detect buffer overflow problems for each individual variable.

These canavari, of course, take up extra space, affecting the size of the stack frame.

+12
source

Due to memory-aligment . Its easier for the CPU to access memory addresses that are multiples of the size of the requested data.
Thus, the compiler fills your structure with clear bytes to align the structure. For instance:

 struct foo { char a int b , c; short d; bool e; double f; }; 

Theoretically, the size of this structure is (Assume that the size of bool is 1 byte, char 1 byte, int 4 bytes, short 2 bytes, double 8 bytes) 20 bytes. But in practice, the compiler adds β€œholes” to the structure to align memory:

  0 | 1 | 2 | 3 -----------+---+---+--- 0x0000 | a | | | -----------+---+---+--- 0x0004 | b | b | b | b -----------+---+---+--- 0x0008 | c | c | c | c -----------+---+---+--- 0x000C | d | d | | -----------+---+---+--- 0x0010 | e | | | -----------+---+---+--- 0x0014 | f | f | f | f -----------+---+---+--- 0x0018 | f | f | f | f -------+---+---+---+--- 
+5
source

I remember that the reason for this is optimization, and possibly because of the size address. Another example of this type is the Boolean type, which typically consumes 8 bits and can only be one. This can vary greatly from different compilers. You can learn more about boolean in Why is there a char and bool of the same size in C ++?

0
source

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


All Articles