Suppose somewhere, somewhere in the program (not at the beginning), we have the following code:

int a = <некое значение>; 

But up to this place, let's say, in our program there were already several hundred other variables, and the program addressed the dynamic memory many times. Is it possible that the system runs out of memory, and the above code is brought to the development of an unhandled exception and the program crash? Or, before this, new [] already has time to call std :: bad_alloc, and such a situation is impossible in principle? In other words, is there a guarantee that there are no exceptions in this case?

In fact, the int a = some_val instruction is simply translated into an assembler command like mov eax, ds [index]; those. The idea is that there should be an exception and should not, the only question is whether the data segment is fully reserved before the program starts for all variables, or whether the acquisition of resources occurs dynamically during the program, as in the case of dynamic memory.

It turns out that the more variable names we have, the more indices in the program that are accessed, and the greater must be the amount of the reserved data segment.

The truth still remains the question of how the data segment is requested - either it represents a certain area in the program code (data section), or else the size for the data segment and its size will be obtained from the system heap when the program is started.

  • one
    - For int a = some_val there is a strong nothrow guarantee . This is intuitively understandable, and I think that it is possible to offer some rigorous justification (although, probably, not too trivial). - What happens to the data segment should not worry you at all during development - it makes sense to operate with higher-level guarantees and contracts. - Costantino Rupert

3 answers 3

If I understand the question correctly, then there is the code:

 func() { ... int a = 22; ... } 

In this case, the memory for the variable a will be placed on the stack and "allocated" when entering the func procedure.

I write "memory is allocated" in quotes, because when entering func the stack pointer register will simply be shifted (actually reduced) by the total amount of local variables. So when accessing a, a stack overflow interrupt is possible. (Even more likely, it will happen when the first function is called, if the stack in func overflows).

The size of the allocated data segment under the stack (it is allocated when the process is spawned) and the ability to control this size depends on the OS and its settings. The default for Windows is 2MB, for Linux it is about 10MB.

Whether the C ++ environment will throw an exception in this case, frankly, I don’t know.

If interested, you can play with the program

 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <unistd.h> void sigh (int s) { write(1,"catch\n",6); exit(1); } main (int ac, char *av[]) { int sz = av[1]? atoi(av[1]): -1; while (sz < 1) { printf ("Enter size\n"); scanf("%d",&sz); } struct sigaction sa; memset (&sa,0,sizeof(sa)); sa.sa_handler = sigh; #ifdef ALTST sa.sa_flags = SA_ONSTACK; stack_t ss; ss.ss_sp = malloc(ss.ss_size=1000000); ss.ss_flags = 0; sigaltstack(&ss,NULL); #endif sigaction(SIGSEGV,&sa,NULL); printf ("Try %d (%x) size\n",sz,sz); char a[sz]; a[0] = 'a'; printf ("first\n"); a[sz-1] = 'z'; printf ("last\n"); exit (0); } avp@avp-ubu1:~/hashcode$ g++ stacksz.c avp@avp-ubu1:~/hashcode$ ./a.out 10400000 Try 10400000 (9eb100) size first last avp@avp-ubu1:~/hashcode$ ./a.out 10500000 Try 10500000 (a037a0) size Ошибка сегментирования avp@avp-ubu1:~/hashcode$ g++ -DALTST stacksz.c avp@avp-ubu1:~/hashcode$ ./a.out 10500000 Try 10500000 (a037a0) size catch avp@avp-ubu1:~/hashcode$ 

The idea, I hope, is clear. Add catch exceptions, etc. cross things.

UPDATE

If someone is interested, you can add code

  struct rlimit lim; int rc = getrlimit(RLIMIT_STACK,&lim); printf ("get = %d stsize: %ld (soft) %ld (hard)\n", rc, (long)lim.rlim_cur,(long)lim.rlim_max); int m = av[2]? atoi(av[2]): 1000000; lim.rlim_cur += m; rc = setrlimit(RLIMIT_STACK,&lim); if (rc < 0) perror("setrlimit"); rc = getrlimit(RLIMIT_STACK,&lim); printf ("get2 = %d stsize: %ld (soft) %ld (hard)\n", rc, (long)lim.rlim_cur,(long)lim.rlim_max); 

and see how it works.

  • Yes Yes Yes. I personally caught the Segmentation fault with a program crash. - gecube

What kind of dynamic memory allocation in general? The place for global variables is reserved in advance, regardless of their visibility area (which, by the way, is well known to those to whom the words tiny, small, compact, medium, large and huge still talk about something ;-) Local variables are placed on the stack, and In the case of code optimization, the stack may not be required.

    If we are talking about C ++, the construct int a = <some value>; allocates memory on the stack. Learn mat. part. The size of the stack is quite a specific value and depends on many factors: the compiler, the operating system, etc. And, in principle, this value can be increased. I myself sometimes used black magic and increased the size of the stack. This was mainly necessary when using recursion. For this, the #pragma construction was used. You can read more specifically here .