Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Asignación de memoria dinámica.

Estas en el tema de Asignación de memoria dinámica. en el foro de C/C++ en Foros del Web. Hola, tengo el siguiente problema: Necesito crear una lista encadenada en un integrado de la familia MSP430, necesito utilizar toda la memoria dinámica posible. Lo ...
  #1 (permalink)  
Antiguo 05/06/2015, 21:30
 
Fecha de Ingreso: mayo-2015
Mensajes: 3
Antigüedad: 9 años
Puntos: 0
Asignación de memoria dinámica.

Hola, tengo el siguiente problema:
Necesito crear una lista encadenada en un integrado de la familia MSP430, necesito utilizar toda la memoria dinámica posible.
Lo que se me había ocurrido era utilizar la función malloc, intentaba ocupar una cantidad importante de memoria con dicha función, de ser posible liberaba esa memoria y creaba también con malloc, un eslabón de la cadena, de esa manera me aseguraba de siempre tener un espacio disponible para el resto de las variables que pudieran aparecer en el programa.
Me enteré hace muy poco que no al no tener sistema operativo, malloc no se comporta como debería. Me gustaría saber una alternativa para reservar memoria e ir creando eslabones, siempre teniendo cuidado de no saturar toda la memoria disponible.

Agradezco cualquier respuesta.
  #2 (permalink)  
Antiguo 08/06/2015, 12:57
 
Fecha de Ingreso: junio-2010
Ubicación: Madrid
Mensajes: 620
Antigüedad: 13 años, 11 meses
Puntos: 73
Respuesta: Asignación de memoria dinámica.

La MSP430 es una familia de microcontroladores, el ""sistema operativo" será el programa que le introduzcas. Sobre el funcionamiento de malloc, pues, no debería haber problemas. Si hay alguna particularidad, tendrá que venir documentada en la documentación correspondiente del compilador.
  #3 (permalink)  
Antiguo 09/06/2015, 02:51
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: Asignación de memoria dinámica.

También puedes hacer una reserva grande al principio, y gestionar tu mismo esa memoria de forma manual.

Un ejemplo para ilustrar el asunto. En este caso se hace una reserva grande y se va utilizando para almacenar ints. Para optimizar el uso de memoria, los "slots" que estén vacíos van a almacenar un valor que se corresponde con el índice del siguiente "slot" vacío. Es decir, inicialmente, si suponemos una reserva para 3 ints, la memoria quedaría tal que:

| 1 | 2 | -1 |

El -1 es para indicar que no hay más memoria libre.

Cuando se libera un "slot" se borra su contenido y se vuelve a almacenar un índice (o -1 si es el único "slot" libre).

Para conocer el primer "slot" libre vamos a usar un puntero.

El ejemplo, dado que símplemente sirve para ilustrar la idea, carece de chequeos y asume que se usa correctamente... no costaría mucho modificarlo para que pudiese almacenar estructuras más complejas.

Ah sí... el main va a usar C++ porque así puedo simplificar el ejemplo.

Bueno, dicho esto, el código de ejemplo:

Código C++:
Ver original
  1. #include <vector>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. typedef struct
  6. {
  7.   int* data;
  8.   int nextIndex;
  9.   size_t size;
  10. } Memory;
  11.  
  12. // Variable global... no acceder a ella directamente!!!!
  13. Memory memory;
  14.  
  15. // Reserva memoria
  16. // Si se hacen dos reservas consecutivas se producirán fugas de memoria!!!
  17. // Retorna 1 si la reserva se ha realizado correctamente
  18. int AllocMemory( size_t size )
  19. {
  20.   memory.data = (int*)malloc( size * sizeof( int ) );
  21.   memory.size = size;
  22.   if( memory.data )
  23.   {
  24.     // Inicialización de la memoria
  25.     // Se almacenan los índices
  26.     size_t i;
  27.     for( i=0; i<size; ++i)
  28.       memory.data[ i ] = i+1;
  29.  
  30.     memory.data[ size - 1] = -1;
  31.  
  32.     // El primer slot libre es el primer elemento de la reserva
  33.     memory.nextIndex = 0;
  34.   }
  35.   else
  36.     memory.nextIndex = -1;
  37.  
  38.   return memory.data != 0;
  39. }
  40.  
  41. // Libera la memoria reservada
  42. void ReleaseMemory( )
  43. {
  44.   free( memory.data );
  45.   memory.data = 0;
  46.   memory.nextIndex = -1;
  47.   memory.size = 0;
  48. }
  49.  
  50. // Reserva un nuevo slot y devuelve un puntero al mismo
  51. // Si no quedan slots libres retornará 0
  52. // El puntero devuelto no se encuentra inicializado
  53. int* ReserveSlot( )
  54. {
  55.   int* to_return = 0;
  56.  
  57.   if( memory.nextIndex >= 0 )
  58.   {
  59.     to_return = &memory.data[ memory.nextIndex ];
  60.     memory.nextIndex = *to_return;
  61.   }
  62.  
  63.   return to_return;
  64. }
  65.  
  66. // Libera un slot previamente reservado
  67. // Se asume que el puntero pertenece a la memoria reservada
  68. void FreeSlot( int* ptr )
  69. {
  70.   *ptr = memory.nextIndex;
  71.   memory.nextIndex = ptr - memory.data;
  72. }
  73.  
  74. // Vuelca el contenido de la memoria por pantalla
  75. // Para depurar
  76. void DumpMemory( char* title )
  77. {
  78.   printf( "%s\n", title );
  79.   size_t i;
  80.   for( i = 0; i < memory.size; ++i )
  81.     printf( "%10X", memory.data[i] );
  82.   printf( "\n\n" );
  83. }
  84.  
  85. int main(int , char **)
  86. {
  87.   std::vector< int* > numbers;
  88.   int* slot = 0;
  89.  
  90.   // Reservamos memoria
  91.   AllocMemory( 16 );
  92.   DumpMemory( "Reserva de memoria" );
  93.  
  94.   // Reservamos 5 slots
  95.   while( numbers.size( ) < 5 )
  96.   {
  97.     slot = ReserveSlot( );
  98.     *slot = 0;
  99.     numbers.push_back( slot );
  100.   }
  101.  
  102.   // Reservamos un 6º slot
  103.   slot = ReserveSlot( );
  104.   numbers.push_back( slot );
  105.   if( slot )
  106.     *slot = 0x100;
  107.  
  108.   DumpMemory( "6 slots reservados" );
  109.  
  110.   // Liberamos el 2º slot.
  111.   // Como el siguiente slot libre es el 7º, en esta posición se almacenará
  112.   // el valor 6 (recuerda que los índices empiezan en 0)
  113.   FreeSlot( numbers[ 1 ] );
  114.  
  115.   // Eliminamos el slot del vector
  116.   numbers.erase( numbers.begin( ) + 1 );
  117.  
  118.   DumpMemory( "Liberado 2o slot" );
  119.  
  120.   // Liberamos el 4o slot.
  121.   // Como el siguiente slot libre es el 2º, en esta posición se almacenará
  122.   // el valor 1
  123.   FreeSlot( numbers[ 2 ] );
  124.  
  125.   // Eliminamos el slot del vector
  126.   numbers.erase( numbers.begin( ) + 2 );
  127.  
  128.   DumpMemory( "Liberado 4o slot" );
  129.  
  130.   // Vamos a usar todos los slots:
  131.   while( numbers.size( ) < 16 )
  132.   {
  133.     slot = ReserveSlot( );
  134.     *slot = 0x12;
  135.     numbers.push_back( slot );
  136.   }
  137.  
  138.   DumpMemory( "Sin slots libres" );
  139.  
  140.   // Si intentamos una reserva nueva... fallará
  141.   slot = ReserveSlot( );
  142.   if( slot == 0 )
  143.     printf( "No hay slots libres!!!!\n" );
  144.   else
  145.     printf( "Slot reservado con éxito\n" );
  146.  
  147.   // Si ahora liberamos, un slot intermedio,
  148.   // al ser el único slot libre,
  149.   // tendrá como siguiente índice -1 (0xFFFFFFFF)
  150.  
  151.   FreeSlot( numbers[ 4 ] );
  152.  
  153.   DumpMemory( "Un Slot libre (el 4o)" );
  154.  
  155.   ReleaseMemory( );
  156.  
  157.   return 0;
  158. }

La ventaja que tiene este mecanismo es que garantizas la memoria al inicio de tu código... además la puedes seguir usando como si fuese memoria dinámica que vas reservando sobre la marcha...

Otra ventaja es que reduces la fragmentación de la memoria.

Un saludo

Etiquetas: malloc, memoria
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:38.