2012-03-31 16 views
8

Tengo curiosidad de saber si es posible determinar el tamaño máximo que una matriz puede tener en C++.Encontrar programáticamente el tamaño máximo de matriz estática en C++

#include <iostream> 

    using namespace std; 

    #define MAX 2000000 

    int main() 
    { 
     long array[MAX]; 
     cout << "Message" << endl; 
     return 0; 
    } 

Esto compila bien, pero luego segfaults tan pronto como lo ejecuto (a pesar de matriz no se hace referencia en realidad). Sé que es el tamaño de la matriz también, porque si lo cambio a 1000000 funciona perfectamente.

Entonces, ¿hay alguna definición en alguna parte o alguna forma de tener #define MAX MAX_ALLOWED_ARRAY_SIZE_FOR_MY_MACHINE_DEFINED_SOMEWHERE_FOR_ME?

Realmente no necesito esto para nada, esta pregunta es por curiosidad.

+0

¿quieres entender el tamaño máximo de matriz en la pila? tal vez la recursión funcione para ti, entonces? no en una sola matriz sino en forma combinada? – tartar

+2

@tar ¿Qué tiene que ver la recursión con esto? –

+0

Esta publicación no responde a su pregunta, pero debería ser una lectura interesante porque habla sobre el mismo problema de fallo seg: http://stackoverflow.com/questions/851122/large-2d-array-gives-segmentation-fault –

Respuesta

10

no hay una manera de determinar esto de forma estática, debido a que el real límite depende de la cantidad de espacio de pila se le ha dado el hilo. Podrías crear un nuevo hilo, darle 10 megabytes de pila, y podrías asignar un arreglo local correspondientemente más grande.

La cantidad que puede asignar en la pila también depende de cuánto se ha utilizado hasta ahora.

+0

Eso tiene sentido, supongo que no entiendo muy bien la diferencia entre cómo se manejan las matrices estáticas y las matrices dinámicas en términos de asignación de memoria en tiempo de ejecución – SirGuy

+3

Cuando declara una variable local, el espacio para toda la matriz se asigna desde pila de espacio (esto es diferente a otros lenguajes como Java). Cuando declara algo global, fuera de una función, el vinculador configura las direcciones de memoria para que el espacio exista incluso antes de que su programa comience a ejecutarse. La pila tiene un tamaño limitado (generalmente 1 megabyte en un SO de escritorio moderno, pero puede variar ampliamente), mientras que el espacio disponible estático es el espacio completo de direcciones de la aplicación de la máquina (2 GB más o menos en un sistema de 32 bits). –

+0

¿Hay alguna diferencia de rendimiento entre estos dos tipos de memoria? Además, _todos los programas usan el mismo espacio estático, incluso cuando no están en ejecución. ¿Hay algún intercambio que ocurra en el espacio estático o si instalas un trillón de programas podrías simplemente agotarte? Supongo que los problemas con esto no aparecen muy a menudo. – SirGuy

4
void foo(int level){ 
int dummy[100]; 
cerr<<level<<endl; 
foo(level+1); 
} 

Entonces, tal vez pueda multiplicar el último nivel impreso por 400 bytes. Las llamadas recursivas ocupan la mayor parte del espacio de la pila, supongo, pero puede obtener un límite inferior. Puedo omitir algo de comprensión de la gestión de la memoria aquí, así que estoy abierto a las correcciones.

Así que esto es lo que obtuve en mi máquina con distintas matrices ficticias.

level array size stack total 
24257  100  9702800 
2597 1000  10388000 
    260 10000  10400000 
    129 20000  10320000 
    64 40000  10240000 
    25 100000  10000000 
    12 200000  9600000 
+0

Entiendo ahora lo que significaba antes, gracias – SirGuy

+0

Jugué con esa solución para aumentar el tamaño de la matriz de enteros. Solo para eliminar la carga de llamadas de funciones adicionales en cada paso. El máximo que obtengo es cuando el tamaño de la matriz es 10000 y el tamaño máximo de la pila en mi máquina (ubuntu 10.04) es 10400000 bytes – tartar

+0

Tenga cuidado con la optimización de la cola de llamadas aquí. –

1

Lea this para comprender las limitaciones que establecen el hardware y el compilador. No creo que pueda tener un MAX definido para que lo use de inmediato.

2

La mayoría de las variables declaradas dentro de las funciones se asignan en the stack, que es básicamente un bloque de memoria de tamaño fijo. Intentar asignar una variable de pila más grande que el tamaño de la pila causará un stack overflow, que es la causa de la segfault.

A menudo, el tamaño de la pila es de 8 MB, por lo que, en una máquina de 64 bits, long max[1000000] tiene tamaño 8*1000000 < 8MB (la pila es "seguro"), pero long max[2000000] tiene tamaño 8*2000000 > 8MB, por lo que los desbordamientos de pila y los segfaults programa.

Por otra parte, asignar dinámicamente la matriz con malloc pone la memoria en the heap, que es básicamente ilimitada (4 GB en una máquina de 32 bits, 17,179,869,184GB en una máquina de 64 bits).

Cuestiones relacionadas