Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why more memory is assigned to a local variable in stack than required in C++?

I was reading about buffer overflow. I found one strange thing about memory assignment of local variable on stack

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

Here allocation is happening on the stack.

Now, In GCC string2 is allocated 4 bytes but if I declare other than power of 2 (upto 16)then it is allocated 16 bytes by the compiler. That means if I allocate string2 in 3,5,6,7,....,15 bytes then it is allocated 16 bytes by the compiler but if I allocate in power of 2 like 1,2,4,8... then it is allocated the exact same size. If I assign above 16 bytes (not power of 2) then it allocates 32 bytes (I guess upto 32 bytes).

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

Anyone know why this kind of assignment???

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

like image 398
Arpit Avatar asked Sep 10 '13 11:09

Arpit


People also ask

Why local variables are allocated on the stack in C?

Advantages of using Stack When a function is called the local variables are stored in a stack, and it is automatically destroyed once returned. A stack is used when a variable is not used outside that function. It allows you to control how memory is allocated and deallocated. Stack automatically cleans up the object.

Does a local variable allocate space on the stack?

When a new local variables is declared, more stack memory is allocated for that function to store the variable. Such allocations make the stack grow downwards. After the function returns, the stack memory of this function is deallocated, which means all local variables become invalid.

Which is stored within the stack memory local variable?

Whenever an object is created, it's always stored in the Heap space and stack memory contains the reference to it. Stack memory only contains local primitive variables and reference variables to objects in heap space.

When the memory is allocated for local variables?

For local variables, the memory they consume is on the stack. This means that they must have a fixed size known at compile time, so that when the function is called, the exact amount of memory needed is added to the stack by changing the value of the stack pointer.

Why is stack faster than heap?

The stack is faster because the access pattern makes it trivial to allocate and deallocate memory from it (a pointer/integer is simply incremented or decremented), while the heap has much more complex bookkeeping involved in an allocation or free.


2 Answers

Stack frame sizes are affected by memory alignment choices, usually a multiple of 4 for 32-bit code and a multiple of 8 for 64-bit code.

Both compilers can include stack frame corruption checking with a canary, an extra 32-bit value at the top of the stack that is initialized at function entry and checked at function exit. If the canary value changed then a program abort occurs because the stack frame is likely to be corrupted, possibly by malicious code, that can alter the function return address and get it to return to an arbitrary location. A very popular malware injection vector.

MSVC has the /RTC option, enabled by default in the Debug configuration. Which adds these canaries in between every local variable. So it can detect buffer overflow problems on each individual variable.

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

like image 114
Hans Passant Avatar answered Oct 05 '22 23:10

Hans Passant


Thats due to memory-aligment. Its easier for the CPU to access to memory addresses which are multiples of the size of the data requested.
So the compiler fills your structure with clear bytes to align the structure. For example:

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

In theory the size of that struct is (Supposing the size of bool is 1 byte, char1 byte, int 4 bytes, short 2 bytes, double 8 bytes) 20 bytes. But in practice, the compiler adds "holes" to the struct to align the 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
-------+---+---+---+---
like image 23
Manu343726 Avatar answered Oct 06 '22 00:10

Manu343726