To analyze such secrets, it is always useful to look at the generated code. I assume that your particular version of the compiler does something different, because my segfaults are with -O0, but not with -O1.
From your program # 1 with g ++ ac -g -O0 and then objdump -S a.out
int main(int argc, char * argv[]) { 8048484: 55 push %ebp 8048485: 89 e5 mov %esp,%ebp
This is a standard stack stack. Nothing is visible here.
8048487: 83 e4 f0 and $0xfffffff0,%esp
Align the stack to a multiple of 16 just in case.
804848a: 81 ec 30 00 b0 00 sub $0xb00030,%esp
Allocate 0xB00030 bytes of stack space. This is 1024 * 1024 * 11 + 48 bytes. There is no memory access, so no exception. An additional 48 bytes use the internal use of the compiler.
8048490: 8b 45 0c mov 0xc(%ebp),%eax 8048493: 89 44 24 1c mov %eax,0x1c(%esp) <--- SEGFAULTS
The first time access to the stack goes beyond ulimit, so it segfaults.
8048497: 65 a1 14 00 00 00 mov %gs:0x14,%eax
Thiis is a stack protector.
804849d: 89 84 24 2c 00 b0 00 mov %eax,0xb0002c(%esp) 80484a4: 31 c0 xor %eax,%eax char buf[1024*1024*11] = {0}; 80484a6: 8d 44 24 2c lea 0x2c(%esp),%eax 80484aa: ba 00 00 b0 00 mov $0xb00000,%edx 80484af: 89 54 24 08 mov %edx,0x8(%esp) 80484b3: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) 80484ba: 00 80484bb: 89 04 24 mov %eax,(%esp) 80484be: e8 d1 fe ff ff call 8048394 <memset@plt>
Initialize an array by calling memset
return 0; 80484c3: b8 00 00 00 00 mov $0x0,%eax }
As you can see, segfault happens when accessing internal variables because they fall below a large array (they should be because there is a stack protector to detect stack splitting).
If you compile with optimization, the compiler notices that you are not doing anything with the array and optimizing it. So nothing sigseg.
Your GCC version is probably a bit super small in non-optimized mode and removes the array. We can analyze it further if you publish the output of objdump -S a.out .