2010-06-16 8 views
5

Este código produce un error de segmentación durante la declaración de la matriz. Estoy confundido sobre por qué sucede esto. Intencionalmente seleccioné 2000000000 como valor porque está por debajo de 2^31 y puede caber en una variable entera.programación en C, ¿por qué esta declaración de matriz grande produce una falla de segmentación?

int main() 
{ 

    int nums_size = 2000000000; 

    int nums[nums_size]; 

    int i; 
    for(i = 0; i < nums_size; i++) { 
     nums[i] = i; 
    } 


    return 0; 

} 

Respuesta

21

Bueno, para empezar, son dos mil millones de enteros. Si tiene un espacio de direcciones de 32 bits y int tiene un tamaño de cuatro bytes en su plataforma (típico para una plataforma de 32 bits), no puede almacenar tantos enteros, punto.

Aún así, solo tiene mucho espacio disponible para usted en la pila, que es donde se encuentran las variables automáticas.

Si necesita una matriz realmente grande, debe asignar dinámicamente utilizando malloc() (y si lo hace, asegúrese de liberarla usando free() cuando haya terminado con ella!).

+0

Incluso si ese no fuera el caso, 2000000000 * 4 = 8,000,000,000 bytes en una plataforma de 32 bits. Eso es casi 2^33, que es más que memoria disponible. –

+0

@Chris: Sí, en realidad no conté los ceros hasta después de haber publicado. ¡Son muchos enteros! –

+0

También es generalmente posible asignar matrices muy grandes con duración de almacenamiento estático. – caf

4
int nums_size = 2000000000; 

int nums[nums_size]; 

No significa que 2000000000 bytes de INT, significa 2000000000 elementos de tipo int, que en una plataforma de 32 bits significa que usted está consumiendo casi 8 GB de memoria - esto es imposible.

+0

... ¡y en la pila!- Kaboom! –

3

Está asignando una matriz gigante en la pila. Prácticamente ningún compilador C/C++ manejará eso correctamente.

Es posible que pueda salirse con la suya moviéndolo a los globales (que asignará el espacio estáticamente mapeando la memoria en el ejecutable en tiempo de compilación), o cambiando a una matriz malloc 'd.

Por supuesto, todavía hay mucha memoria que pedir de una sola vez, pero al menos los métodos que menciono evitarán una segfault inmediata.

+1

El compilador lo manejará correctamente (si estaba dentro del tamaño de la memoria 2^32), pero el sistema operativo no permitirá que la pila crezca tanto. –

+0

no solo C/C++ prácticamente cualquier lenguaje que haga asignación basada en la pila (es decir, casi todos) – Spudd86

0

Esta versión funciona muy bien en mi PC:

const int nums_size = 2000000000; 
int nums[nums_size]; 

int main() 
{ 
    int i; 
    for(i = 0; i < nums_size; i++) { 
     nums[i] = i; 
    } 

    return 0; 
} 

(Bueno, vamos a ser honestos, inicia bien, pero pronto entra en intercambio..)

+0

Y supongo que su versión se ejecuta en una plataforma de 64 bits. De su comentario de 2^31, definitivamente no está ejecutando un sistema operativo de 64 bits. –

+0

-1 por tener más memoria que yo (es broma). – cdonner

+0

@Chris el comentario 2^31 no le dice si está ejecutando 32 bits o 64 bits. Creo que gcc tiene por defecto las entradas de 32 bits en las plataformas de 64 bits. – sigfpe

2

Las variables locales se asignan en la pila . Hay un espacio de pila de cantidad fija (generalmente de 1 MB a 8 MB, varía según el sistema operativo) proporcionado a la aplicación. La regla general es usar malloc() para asignar grandes cantidades de datos.

1

La respuesta a su pregunta es simple: stackoverflow. No, no, no el sitio, sino el proceso real de "desbordamiento de la pila". No tiene suficiente stack para almacenar esa matriz. Tan sencillo como eso. Hacer esto en sistemas con memoria limitada es pura locura. También vea this question.

Cuestiones relacionadas