Fallo de segmentación en matrices de gran tamaño

Resuelto Mayank asked hace 14 años • 0 respuestas

El siguiente código me da un error de segmentación cuando lo ejecuto en una máquina de 2 Gb, pero funciona en una máquina de 4 GB.

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

El tamaño de la matriz es de sólo 4 Mb. ¿Existe un límite en el tamaño de una matriz que se puede utilizar en C++?

Mayank avatar Dec 04 '09 22:12 Mayank
Aceptado

Probablemente estés recibiendo un desbordamiento de pila aquí. La matriz es demasiado grande para caber en la región de la pila de su programa; El límite de crecimiento de la pila suele ser de 8 MiB o 1 MiB para el código de espacio de usuario en la mayoría de los sistemas operativos de escritorio/servidor convencionales. (Las implementaciones normales de C++ utilizan la pila asm para el almacenamiento automático, es decir, staticmatrices de variables no locales. Esto hace que la desasignación se realice de forma gratuita cuando las funciones regresan o una excepción se propaga a través de ellas).

Si asigna dinámicamente la matriz, debería estar bien, suponiendo que su máquina tenga suficiente memoria.

int* array = new int[1000000];    // may throw std::bad_alloc

Pero recuerde que esto requerirá que acceda a delete[]la matriz manualmente para evitar pérdidas de memoria, incluso si su función sale a través de una excepción. Se desaconseja encarecidamente la creación/eliminación manual en C++ moderno, prefiera RAII .


Una mejor solución sería utilizarstd::vector<int> array ( cppreference ). Puedes reservar espacio para 1000000 elementos, si sabes cuánto crecerá. O incluso resizeconstruirlos de forma predeterminada (es decir, inicializar la memoria a cero, a diferencia de cuando se declara una matriz de estilo C simple sin inicializador), comostd::vector<int> array(1000000)

Cuando el std::vectorobjeto sale del alcance, su destructor desasignará el almacenamiento por usted, incluso si eso sucede a través de una excepción en una función secundaria capturada por una función principal.

Charles Salvia avatar Dec 04 '2009 15:12 Charles Salvia

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

No lo asigne localmente en la pila, utilice otro lugar en su lugar. Esto se puede lograr haciendo que el objeto sea global o asignándolo en el montón global . Las variables globales están bien, si no las usas desde ninguna otra unidad de compilación. Para asegurarse de que esto no suceda por accidente, agregue un especificador de almacenamiento estático; de lo contrario, simplemente use el montón.

Esto se asignará en el segmento BSS, que es parte del montón. Dado que está en almacenamiento estático, se inicializa en cero si no se especifica lo contrario, a diferencia de las variables locales (almacenamiento automático), incluidas las matrices.

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

Un inicializador distinto de cero hará que un compilador asigne en el segmento DATOS, que también forma parte del montón. (Y todos los datos para el inicializador de matriz ocuparán espacio en el ejecutable, incluidos todos los ceros finales implícitos, en lugar de solo un tamaño para inicio cero en el BSS)

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

Esto se asignará en alguna ubicación no especificada del montón:

int main()
{
   int* c = new int[1000000];  // size can be a variable, unlike with static storage
   cout << "done\n";
   delete[] c;            // dynamic storage needs manual freeing
   return 0;
}
Gunther Piez avatar Dec 04 '2009 15:12 Gunther Piez

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

ulimit -s unlimited

Pero cuidado, la memoria es un recurso limitado y un gran poder conlleva grandes responsabilidades :)

RSFalcon7 avatar Nov 08 '2013 15:11 RSFalcon7

Su matriz se está asignando en la pila; en este caso, intente asignar una matriz del mismo tamaño usando alloc.

rerun avatar Dec 04 '2009 15:12 rerun

Porque almacena la matriz en la pila. Deberías guardarlo en el montón. Consulte este enlace para comprender el concepto de montón y pila.

Narek avatar Jan 07 '2011 23:01 Narek