c memory malloc stack-overflow

malloc calloc realloc in c



¿Qué está causando un desbordamiento de pila? (6)

Puede pensar que es una coincidencia que el tema de mi pregunta sea similar al nombre del foro, pero en realidad lo conseguí buscando en Google el término "desbordamiento de pila".

Uso el simulador de red OPNET en el que programo usando C. Creo que tengo un problema con los tamaños de matriz grande. Parece que estoy alcanzando algún tipo de limitación de asignación de memoria. Puede tener que ver con OPNET, Windows, la memoria de mi computadora portátil o, con mayor probabilidad, el lenguaje C. El problema se produce cuando trato de usar matrices anidadas con un número total de elementos que llegan a varios miles de enteros. Creo que estoy excediendo un límite general de asignación de memoria y me pregunto si hay una manera de aumentar este límite. Aquí está la descripción exacta del problema:

Básicamente tengo una tabla de enrutamiento. Llamémoslo routing_tbl [n], lo que significa que estoy soportando 30 nodos (enrutadores). Ahora, para cada nodo en esta tabla, guardo información. sobre muchos (cientos) caminos disponibles, en una matriz llamada rutas [p]. Nuevamente, para cada ruta en esta matriz, guardo la lista de nodos que le pertenecen en una matriz llamada saltos [h]. Por lo tanto, estoy usando al menos nph enteros de memoria, pero esta tabla también contiene otra información. En la misma función, también estoy usando otra matriz anidada que también consume casi 40,000 enteros. Tan pronto como ejecuto mi simulación, deja de quejarse sobre el desbordamiento de la pila. Funciona cuando reduzco el tamaño total de la tabla de enrutamiento. ¿Qué crees que causa el problema y cómo se puede resolver? Muy apreciado Ali


De alguna manera estás usando mucha pila. Las causas posibles incluyen que está creando la tabla de enrutamiento en la pila, la está pasando en la pila, o bien está generando muchas llamadas (por ejemplo, procesando todo de forma recursiva).

En los primeros dos casos, debe crearlo en el montón y pasarle un puntero. En el tercer caso necesitarás reescribir tu algoritmo de forma iterativa.


Los desbordamientos de pila pueden ocurrir en C cuando la cantidad de llamadas recursivas incorporadas es demasiado alta. ¿Tal vez llama una función de sí mismo demasiadas veces?

Este error también puede deberse a la asignación de demasiada memoria en las declaraciones estáticas. Puede cambiar a asignaciones dinámicas a través de malloc () para solucionar este tipo de problema.

¿Hay alguna razón por la cual no puedes usar el depurador en este programa?


Depende de dónde hayas declarado la variable.

Una variable local (es decir, una declarada en la pila está limitada por el tamaño de fotograma máximo). Este es un límite del compilador que está utilizando (y generalmente se puede ajustar con indicadores de compilación).

Un objeto dinámicamente asignado (es decir, uno que está en el montón) está limitado por la cantidad de memoria disponible. Esta es una propiedad del sistema operativo (y técnicamente puede ser más grande la memoria física si tiene un sistema operativo inteligente).


Es poco probable que te topes con un desbordamiento de pila con la compilación C no enhebrada a menos que hagas algo particularmente atroz como tener una recursión fugitiva o una fuga de memoria cósmica. Sin embargo, su simulador probablemente tenga un paquete de subprocesos que impondrá límites de tamaño de pila. Cuando inicie un nuevo hilo, asignará un trozo de memoria para la pila de ese hilo. Probablemente, hay un parámetro que puede establecer en algún lugar que establece el tamaño de pila predeterminado, o puede haber una manera de hacer crecer la pila de forma dinámica. Por ejemplo, pthreads tiene una función pthread_attr_setstacksize () a la que llama antes de comenzar un nuevo hilo para establecer su tamaño. Su simulador puede o no usar pthreads. Consulte la documentación de referencia de su simulador.


Muchos sistemas operativos expanden dinámicamente la pila a medida que la utilizas más. Cuando comienza a escribir en una dirección de memoria que está más allá de la pila, el sistema operativo asume que su pila ha crecido un poco más y le asigna una página adicional (generalmente 4096 Kb en x86 - exactamente 1024 ints).

El problema es que, en el x86 (y algunas otras arquitecturas), la pila crece hacia abajo, pero las matrices en C crecen hacia arriba . Esto significa que si accede al inicio de una matriz grande, accederá a la memoria que está a más de una página del borde de la pila.

Si inicializa su matriz a 0 comenzando desde el final de la matriz (eso es correcto, haga un ciclo for para hacerlo), los errores podrían desaparecer. Si lo hacen, este es realmente el problema.

Es posible que pueda encontrar algunas funciones de la API del sistema operativo para forzar la asignación de la pila, o los pragmas / indicadores del compilador. No estoy seguro de cómo esto se puede hacer de forma portátil, excepto, por supuesto, para usar malloc () y free ()!


Puede ser útil si publica algún código. Edite la pregunta para incluir la función del problema y el error.

Mientras tanto, aquí hay una respuesta muy genérica:

Las dos causas principales de un desbordamiento de pila son 1) una función recursiva, o 2) la asignación de un gran número de variables locales.

Recursión

si su función se llama a sí misma, así:

int recurse(int number) { return (recurse(number)); }

Como las variables locales y los argumentos de las funciones se almacenan en la pila, llenarán la pila y causarán un desbordamiento de la pila.

Grandes variables locales

Si intenta asignar una gran variedad de variables locales, puede desbordar la pila de una sola vez. Una función como esta puede causar el problema:

void hugeStack (void) { unsigned long long reallyBig[100000000][1000000000]; ... }

Hay una respuesta bastante detallada a esta pregunta similar .