[C con Clase] Reserva de memoria a partir de una dirección dada.

Jorge Vega Sanchez memmaker650 en gmail.com
Mar Jun 22 11:56:13 CEST 2010


Buenas.

Otra preguntita que esta semana estoy pedigüeño.

Estoy tratando de utilizar una pila dentro de los hilos (POSIX en mi caso). Dado que se dice que al crear un hilo se crea un espacio para la pila del hilo. Bueno esto es lo de menos.

La cosa es que consigo la dirección de este  espacio de memoria reservado para la pila y el tamaño de este espacio (size_t).

Al tratar de escribir 3 o 4 datos y posteriormente tratar de sacar uno de ellos como mera prueba sucede que al tratar de meter el primer dato me sale un SEGMENTATION FAULT asín de grande.
Supongo que me sale porque estoy intentado entrar en una zona de memoria no reservada para mi (aunque se supone que si). Bueno entonces me gustaría saber si hay alguna forma de reservar ese espacio.

Con malloc reservas una cantidad de memoria y te devuelve el puntero que apunta a esa zona. Yo lo que busco es un malloc pero dandole yo además la dirección de inicio de la pila.

Pongo el código por si alguno le interesa:



#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

#define NTHREADS 1

using namespace std;
 
pthread_attr_t attr;

class STACK
{ 
  public:
     size_t apilados;        // Numero de objetos en LA PILA
     size_t tamanyo_pila;
     int tamanyo;
     int *addr_top, *addr_bottom;
     
     void init(void *dir, int tam); 
     void clean();        // Vacia LA PILA
     void push(int v);     // Agrega Valores en el tope de la PILA
     int pop();           // Retorna y elimina el tope de la PILA
}; 
// La pila por defecto en un Thread tiene un tamaño de 1MB=1024x1024=1048576 --> 32bit/word=32768 datos
// Supongo que nunca vamos a llenar ni de lejos la pila.

void STACK::init(void *dir, int tam)        // Inicializacion de la PILA
{
  apilados=0;	// Asinamos valores
  addr_top=addr_bottom=(int*)dir;
  tamanyo_pila=tam;
} 

void STACK::clean()        // Vacia la PILA
{
  apilados=0;
  for(int i=0; i<=apilados; i++)
  {
  	free(addr_top); 		// Libero el espacio utilizado por la pila 
  	addr_top+=1;
  }
} 

//Se Agrega(PUSH) un valor en el tope de la pila
void STACK::push(int v)    
{
	// Apilamos el elemento y apuntamos a la siguiente posicion de memoria
   	tamanyo=sizeof(v);
   	cout << "introducimos dato" << endl;
   	*addr_bottom=v;
   	addr_bottom+=1;
   	apilados++; 	
}
 
// Se Elimina (POP) el ultimo valor de la pila
// y retorna el nuevo tope
int STACK::pop()
{                         
  if(apilados>0)         
  {
    	apilados--;
    	addr_top+=1; // Delpazo el tope de la pila
    	cout << "El valor del tope eliminado era: ";
    	return(*(addr_top-1));
  }
  else
  {
  		cout << "No existen datos para eliminar.  ERROR ";
  		return 0;
  } 
} 
 
void *funcion(void *threadid)
{
   void  *stackaddr;
   size_t stacksize;
   STACK pila;
   
    cout << "Hilo 1 DEntro " << endl;
   // Tomar la dirección de comienzo de la pila
   int flag = pthread_attr_getstackaddr(&attr, &stackaddr);
   cout << "Flag: " << flag << endl;
   /* if (flag != 0) 
   {                                           
      printf("pthread_attr_getstackaddr returned: %d\n", flag); 
      //return -1;                                                                  
   } 
   else 
   {
      printf("Retrieved stackaddr is %d \n", stackaddr);
   } */
   
   // Tamaño de la pila del Thread
   pthread_attr_getstacksize (&attr, &stacksize);
   cout << "Tamaño pila Hilo 1: " << stacksize << endl;
   
   //Manejo de la Pila
   cout << "inicializamos la pila: " << endl;
   pila.init(stackaddr, stacksize);
   
   cout << "Metemos datos a la pila: " << endl;
   pila.push(43);
   cout << "Dato 1 para pila: " << stacksize << endl;
   pila.push(325);
   cout << "Dato 2 para pila:: " << stacksize << endl;
   pila.push(4);
   
   cout << "Dato 3 para pila: " << endl;
   pila.pop();
   
   cout << "Liberamos espacio de la pila: " << endl;
   pila.clean();
   
   pthread_exit(NULL);
}
 
int main(int argc, char *argv[])
{
   pthread_t threads[NTHREADS];
   size_t stacksize;
   int rc;
   long t;
 
   pthread_attr_init(&attr);
   
   int err=pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
   if (err)
      {
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         return -1;
      }
   
   pthread_attr_getstacksize (&attr, &stacksize);
   printf("Default stack size = %li\n", stacksize);
   
   // pthread_attr_setstacksize (&attr, stacksize);	// En este caso me quedo con el tamaño por defecto
   printf("Creating threads with stack size = %li bytes\n",stacksize);
   for(t=0; t<NTHREADS; t++)
   {
      rc = pthread_create(&threads[t], &attr, funcion, (void *)t);
      if (rc)
      {
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         return -1;
      }
   }
   
   printf("Created %ld threads.\n", t);
   
   for(t=0; t<NTHREADS; t++)
   {
   	pthread_join(threads[t], NULL);
   }
	
}



Más información sobre la lista de distribución Cconclase