2009-07-23 20 views
65

Si declaro una estructura de datos globalmente en una aplicación C++, ¿consume memoria de pila o memoria de pila?¿Gestión de memoria global en C++ en stack o heap?

Por ejemplo

struct AAA 
{ 

.../.../. 
../../.. 
}arr[59652323]; 
+1

también, ¿cuál es la diferencia entre una variable global y una variable estática (dentro de una función). Tienen que vivir durante la vida del programa ... – user128026

+0

de acuerdo, pero hay una diferencia entre la accesibilidad –

+0

@dspinozzi: los constructores de variables globales se llaman antes de main(), pero los constructores de variables estáticas se llaman la primera vez que la función se llama. Ambos tipos de variables suelen almacenarse en las mismas partes de la memoria: creo que GCC las coloca en la sección de datos. – Neil

Respuesta

123

Como yo no estaba satisfecho con las respuestas, y espero que el karjatkar Sameer quiere aprender algo más que un simple sí/no contesta, aquí tienes.

Normalmente, un proceso ha 5 diferentes áreas de memoria asignada

  1. Código - segmento de texto
  2. datos iniciada - segmento de datos
  3. datos no inicializados - bss segmento
  4. Heap
  5. Stack

Si realmente desea aprender lo que se guarda, donde a continuación, leer y añadirlas a éstos:

COMPILER, ASSEMBLER, LINKER AND LOADER: A BRIEF STORY (w.5 vistazo a la tabla)

Anatomy of a Program in Memory

alt text http://www.tenouk.com/ModuleW_files/ccompilerlinker006.png

+0

¿Eso significa que los datos no inicializados - bss y los datos inicializados - son parte del montón? –

+0

No, no son parte del montón, están en diferentes áreas como estaba escrito en mi respuesta (las 5 áreas diferentes). El montón y la pila ocupan la memoria virtual encima de los segmentos de texto y datos. – Milan

+6

El punto importante es que los segmentos bss y de datos se asignan cuando el programa se carga por primera vez en la memoria, y su tamaño no cambia mientras se ejecuta. El contenido del montón, por el contrario, es volátil y cambia a lo largo de la ejecución, a medida que se realizan operaciones de memoria dinámica. – quark

6

Ni. Es una sección de datos.

+0

Depende si la memoria global se asignó en línea o se asignó dinámicamente desde la aplicación –

+1

Si una memoria se asignó dinámicamente no es global (en un sentido de variable global) – EFraim

+0

que es discutible :) –

5

memoria global es preasignados en un bloque de memoria fija, o en el montón, dependiendo de cómo se asigna por la aplicación:

byte x[10]; // pre-allocated by the compiler in some fixed memory block 
byte *y 

main() 
{ 
    y = malloc(10); // allocated on the heap 
} 

EDITAR:

La pregunta es confuso: Si asigno una estructura de datos globalmente en una aplicación C++, ¿consume memoria de pila o memoria de pila?

"allocate"? Eso podría significar muchas cosas, incluso llamar a malloc(). Hubiera sido diferente si la pregunta fuera "si declaro e inicializo una estructura de datos globalmente".

Hace muchos años, cuando las CPU aún usaban segmentos de 64K, algunos compiladores eran lo suficientemente inteligentes como para asignar memoria dinámicamente desde el montón en lugar de reservar un bloque en el segmento .data (debido a limitaciones en la arquitectura de memoria).

Creo que soy demasiado viejo ....

+0

Eso es semántica. Supongo que vale la pena un voto negativo –

+0

Está "asignado en el montón" y eso es bastante correcto. A menos que esta pregunta sea marcada como "novato" o "principiante", esto debería ser un recordatorio suficiente de lo que está sucediendo. –

+0

@Don: No. Lo global es el puntero y no la memoria a la que apunta. Puede manejar la memoria de la manera que desee. Ni está allí para quedarse durante toda la carrera. Incluso puedes apuntar a la pila a veces. – EFraim

-3

Si se están asignando explícitamente la memoria de sí mismo mediante malloc nuevo o, entonces, que se asignará en el montón. Si el compilador está asignando la memoria, entonces se asignará en la pila.

+0

la memoria global nunca se asigna en la pila. La pila solo se usa para variables locales y los parámetros –

+0

las variables de pila se "destruyen" cuando la función devuelve – user128026

13

Normalmente no consume ninguno. Intenta asignarlos en un segmento de memoria que probablemente permanezca en tamaño constante para la ejecución del programa. Puede ser bss, stack, heap o data.

+0

Al editar el archivo boot.ini podemos extender la memoria virtual a 3GB. Como sabio, ¿hay algún ajuste para el segmento de memoria? –

+0

Eso sería inútil, porque el tamaño de la memoria estáticamente asignada nunca puede cambiar –

-1

variables globales viven en el montón. estos son un caso especial porque viven durante la vida del programa

0

El objeto global en sí ocupará la memoria que el tiempo de ejecución o el compilador reserven antes de que se ejecute main, esto no es un costo de tiempo de ejecución variable, así que ni montón.

Si el ctor del objeto asigna memoria, estará en el montón, y las asignaciones posteriores del objeto serán asignaciones de pila.

Depende de la naturaleza exacta del objeto global, si es un puntero o si el objeto entero es global.

26

El problema aquí es la pregunta. Supongamos que tienes una pequeña C (++ así, que manejan este de la misma manera) programa como este:

/* my.c */ 

char * str = "Your dog has fleas."; /* 1 */ 
char * buf0 ;       /* 2 */ 

int main(){ 
    char * str2 = "Don't make fun of my dog." ; /* 3 */ 
    static char * str3 = str;   /* 4 */ 
    char * buf1 ;      /* 5 */ 
    buf0 = malloc(BUFSIZ);   /* 6 */ 
    buf1 = malloc(BUFSIZ);   /* 7 */ 

    return 0; 
} 
  1. Esto no es ni asignado en la pila ni sobre el montón. En cambio, se asigna como datos estáticos y se coloca en su propio segmento de memoria en la mayoría de las máquinas modernas. La cadena real también se asigna como datos estáticos y se coloca en un segmento de solo lectura en máquinas de pensamiento correcto.
  2. es simplemente un puntero estático asignado; espacio para una dirección, en datos estáticos.
  3. tiene el puntero asignado en la pila y se desasignará cuando vuelva main. La cadena, dado que es una constante, se asigna en el espacio de datos estáticos junto con las otras cadenas.
  4. se asigna exactamente como en 2. La palabra clave static le dice que no debe asignarse en la pila.
  5. ... pero buf1 está en la pila, y
  6. ... el espacio de búfer malloc'ed está en el montón.
  7. Y, por cierto, los niños no prueban esto en casa. malloc tiene un valor de retorno de interés; debe siempre verificar el valor de retorno.

Por ejemplo:

char * bfr; 
if((bfr = malloc(SIZE)) == NULL){ 
    /* malloc failed OMG */ 
    exit(-1); 
} 
+0

El espacio del búfer mallado no tiene nada que ver con las variables globales. Solo los punteros son globales. Por favor, para no confundir a la gente más. – EFraim

+7

Oh, no seas tonto. El interlocutor claramente no tenía claro qué fue donde, así que escribí una respuesta que estaba dirigida a mejorar su comprensión. –

2

Ni declarar una estructura de datos globalmente en un C++ consume montón o memoria de pila. En realidad, las variables globales generalmente se asignan en un segmento de datos cuyo tamaño permanece sin cambios durante todo el programa. Las pilas y los montones se usan generalmente para las variables que se crean y se destruyen durante la ejecución del programa.

Program Memory Space