2009-12-04 17 views
79

El siguiente código me da un error de segmentación cuando se ejecuta en una máquina de 2 Gb, pero funciona en una máquina de 4 GB.Error de segmentación en tamaños de matriz grande

int main() 
{ 
    int c[1000000]; 
    cout << "done\n"; 
    return 0; 
} 

El tamaño de la matriz es de solo 4Mb. ¿Hay un límite en el tamaño de una matriz que se puede usar en C++?

Respuesta

93

Probablemente estés recibiendo un desbordamiento de pila aquí. La matriz es demasiado grande para caber en el espacio de direcciones de la pila de su programa.

Si asigna la matriz en el montón, debería estar bien, suponiendo que su máquina tiene suficiente memoria.

int* array = new int[1000000];

Pero recuerde que esto se requerirá a delete[] la matriz. Una mejor solución sería usar std::vector<int> y cambiar su tamaño a 1000000 elementos.

+0

Gracias por la respuesta, pero podría explicarme por qué las matrices se asignan en la pila y por qué no en la memoria principal del programa. – Mayank

+9

El código dado se asigna a la pila porque está especificado como una matriz con un número constante de elementos en tiempo de compilación. Los valores solo se ponen en el montón con malloc, nuevo, etc. –

+3

Todos los varables automáticos se asignan en la pila. Si nos fijamos en lo que se puede descartar, verá el tamaño de las variables locales restadas del puntero de la pila.Cuando llama a malloc o calloc o cualquiera de las funciones de memoria, las funciones van y encuentran bloques de memoria lo suficientemente grandes como para satisfacer su pedido. – rerun

2

Su matriz se está asignando en la pila en este caso intento de asignar una matriz del mismo tamaño utilizando alloc.

46

En C o C++, los objetos locales se suelen asignar a la pila. Está asignando una matriz grande en la pila, más de lo que la pila puede manejar, por lo que obtiene un stackoverflow.

No lo asigne local en la pila, use otro lugar. Esto se puede lograr haciendo el objeto global o asignándolo en el montón global. Las variables globales son correctas, si no usa la de cualquier otra unidad de compilación. Para asegurarse de que esto no ocurra por accidente, agregue un especificador de almacenamiento estático; de lo contrario, simplemente use el montón.

Este asignará en el segmento de BSS, que es una parte de la pila:

static int c[1000000]; 
int main() 
{ 
    cout << "done\n"; 
    return 0; 
} 

Este asignará en el segmento de datos, que es una parte de la pila demasiado:

int c[1000000] = {}; 
int main() 
{ 
    cout << "done\n"; 
    return 0; 
} 
Este

asignará en algún lugar no especificado en el montón:

int main() 
{ 
    int* c = new int[1000000]; 
    cout << "done\n"; 
    return 0; 
} 
+0

Si utiliza el tercer patrón, asignando en el montón, no se olvide de eliminar [] el puntero en algún momento o se perderá la memoria. O busque punteros inteligentes. – meowsqueak

+6

@meowsqueak Por supuesto, es una buena práctica 'borrar' en cualquier lugar que asigne con 'nuevo'. Pero si está seguro de que asigna memoria solo una vez (como en main), no es estrictamente necesario: se garantiza que la memoria se liberará a la salida de main incluso sin 'delete' explícito. – hirschhornsalz

+0

'at'drhirsch (¿cómo se hace un at-character de todos modos?) - sí, un comentario justo. Como el OP parece nuevo en el lenguaje, solo quería asegurarme de que ellos, y cualquier otra persona que viese su buena respuesta, estuvieran al tanto de las implicaciones de la tercera opción si se usa en general. – meowsqueak

2

Debido a almacenar la matriz en el sta ck. Deberías almacenarlo en el montón. Consulte this link para comprender el concepto del montón y la pila.

6

Además, si está ejecutando en la mayoría de los sistemas UNIX & Linux puede aumentar temporalmente el tamaño de la pila mediante el siguiente comando:

ulimit -s unlimited 

Pero tenga cuidado, la memoria es un recurso limitado y con un gran poder viene gran responsabilidades :)

+0

Esta es la solución, pero recomiendo a todos que sean extremadamente cautelosos al eliminar estos límites predeterminados en el tamaño de la pila del programa. Experimentarás no solo una caída de rendimiento severa, sino que tu sistema podría fallar. Por ejemplo, traté de ordenar una matriz con 16 000 000 de elementos enteros con quicksort en una máquina con 4 GB de RAM y mi sistema casi murió. LOL – rbaleksandar

+0

@rbaleksandar Creo que ~ 16MB programa casi mata tu máquina porque estabas trabajando con varias copias de la matriz (¿puede ser una por llamada a función?) Prueba una implementación más consciente de la memoria;) – RSFalcon7

+0

Estoy bastante seguro de que el manejo de la matriz está bien ya que estoy pasando por referencia y no por valor. Lo mismo sucede con bubblesort. Demonios, incluso si mi implementación de quicksort aspira a bubblesort es algo que posiblemente no puedas implementar incorrectamente. LOL – rbaleksandar

Cuestiones relacionadas