More discussions about stack size: default stack size on modern Linux?
(In general SuSE/Debian/Ubuntu derived systems have 8MB limits, Red Hat/Scientific Linux/Fedora derivatives have 10MB. Usually. You can change it of course.)
To summarize what everyone has said, local variables that go on the stack will automatically be freed by definition; the values may sit in memory for a while but you shouldn't access them, as the values might change unexpectedly. (The operating system can even free that memory page, since it's "free", and you could get a segfault.) Some types of variables (static variables, string literals) are normally stored in the data segment. They persist from when the program is loaded until it's unloaded from memory, so they're "freed" when the operating system removes your program from memory.
It's dangerous to predict how much memory will be used on the stack: even without compiler optimizations that shift stuff around, there may be padding involved. Why don't we find out? Comments in blue.
Code:
$ uname -srm
Linux 3.2.0-2-amd64 x86_64 (I'm using a 64-bit Linux system)
$ cat code.c
void test_func(){
long a = 1; //4 bytes
long b = 2; //4 bytes
long c = 3; //4 bytes
long d = 4; //4 bytes
char text[] = "Hello, this is some text!"; //26 bytes
//Total memory usage: 42 bytes
}
int main() {
test_func(); (added a simple main)
return 0;
}
$ gcc -g code.c -o code (compile with debugging info)
$ gdb -q code (start the debugger in quiet mode)
Reading symbols from /tmp/code...done.
(gdb) start
Temporary breakpoint 1 at 0x4004ee: file code.c, line 13.
Starting program: /tmp/code
Temporary breakpoint 1, main () at code.c:13
13 test_func();
(gdb) s (step into the function)
test_func () at code.c:3
3 long a = 1; //4 bytes
(gdb) p/x $esp
$2 = 0xffffe320
(gdb) p/x $ebp
$3 = 0xffffe320 (stack pointer/esp and base pointer/ebp are the same, means no stack space is used yet)
(gdb) l
1 void test_func(){
2
3 long a = 1; //4 bytes
4 long b = 2; //4 bytes
5 long c = 3; //4 bytes
6 long d = 4; //4 bytes
7
8 char text[] = "Hello, this is some text!"; //26 bytes
9
10 //Total memory usage: 42 bytes
(gdb) n (let's keep stepping)
4 long b = 2; //4 bytes
(gdb)
5 long c = 3; //4 bytes
(gdb)
6 long d = 4; //4 bytes
(gdb)
8 char text[] = "Hello, this is some text!"; //26 bytes
(gdb) n
11 }
(gdb) p/x $esp
$7 = 0xffffe320
(gdb) p/x $ebp
$8 = 0xffffe320 (still no stack space used??)
(gdb) disass test_func (let's look at the assembly)
Dump of assembler code for function test_func:
0x0000000000400494 <+0>: push %rbp
0x0000000000400495 <+1>: mov %rsp,%rbp
0x0000000000400498 <+4>: movq $0x1,-0x8(%rbp)
0x00000000004004a0 <+12>: movq $0x2,-0x10(%rbp)
0x00000000004004a8 <+20>: movq $0x3,-0x18(%rbp)
0x00000000004004b0 <+28>: movq $0x4,-0x20(%rbp)
0x00000000004004b8 <+36>: movl $0x6c6c6548,-0x40(%rbp)
0x00000000004004bf <+43>: movl $0x74202c6f,-0x3c(%rbp)
0x00000000004004c6 <+50>: movl $0x20736968,-0x38(%rbp)
0x00000000004004cd <+57>: movl $0x73207369,-0x34(%rbp)
0x00000000004004d4 <+64>: movl $0x20656d6f,-0x30(%rbp)
0x00000000004004db <+71>: movl $0x74786574,-0x2c(%rbp)
0x00000000004004e2 <+78>: movw $0x21,-0x28(%rbp)
=> 0x00000000004004e8 <+84>: pop %rbp
0x00000000004004e9 <+85>: retq
End of assembler dump.
(gdb)
Basically what happened is that on my 64-bit machine, the compiler decided that it had enough registers to store all of test_func's local variables in registers! So there was actually no stack space used by your variables. With optimizations enabled, the code turns into
Code:
(gdb) disass test_func
Dump of assembler code for function test_func:
0x00000000004004a0 <+0>: repz retq
End of assembler dump.
(gdb)
Which as you might guess is assembly-speak for "do nothing".
Moral of this: compilers have many different resources available to them and they're smarter than you give them credit for. You might think you're saving a byte or wasting some clock cycles or whatever, but a lot of the time it doesn't even matter. The compiler will figure it out.