reservar memoria para punteros en C

Iniciado por Ghalad, 24 Mayo 2010, 18:28 PM

0 Miembros y 4 Visitantes están viendo este tema.

Eternal Idol

Vos queres acceder a:
lista[0][i]

Y estas accediendo a:
lista[i][0]

Podes hacerlo como muestro arriba de todo o asi:
(*lista)[i]
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Ghalad

#11
estoy haciendo una prueba y calculo que esta vez hice bien el tema de la lista pero hay algo que me esta fallando en el programa y no me doy cuenta que es, porque al finalizar me salta un mensaje del visual studio preguntando si quiero debuggearlo. A ver que me decin ustedes.
Código (cpp) [Seleccionar]
char** obtenerLista(int *contador)
{
      int cont = 0;
      char buf[50], **lista;
     
      for(int i = 0; i < 10; i++)
      {
              printf("Ingresa cadena: ");
              fgets(buf, 50, stdin);
              buf[strlen(buf)-1] = '\0';
             
              if(strlen(buf) > 0){
                  lista = (char**)realloc(lista, sizeof(char*));
                  lista[cont]= (char*)malloc( (sizeof(char)*strlen(buf))+1);
                  strcpy(lista[cont], buf);
                   ++cont;
              }
      }
      *contador = cont;
      return lista;
}


Código (cpp) [Seleccionar]
int main(){
char **lista;
   int contador;

   lista = obtenerLista(&contador);
   
   for(int i =0; i < contador; i++){
       printf("grupo %d: %s\n", i, lista[i]);
       }
       
       
       
   for(int i=0; i<contador; i++){
           free(lista[i]);
           }
   free(lista);
   
   system("pause");
   return 0;
}

Eternal Idol

lista = (char**)realloc(lista, sizeof(char*));

lista es un puntero indefinido la primera vez que se llama a realloc (si lo inicializas a 0 es otra cosa) y ademas siempre reservas la misma cantidad de memoria (un puntero).
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Ghalad

claro porque la idea es que, si hay una nue3va cadena a agregar se reserve memoria para un nuevo puntero a string y despues se reserve memoria para ese string. Segun entendi si el puntero no tienen memoria asiganada el realloc funciona como un malloc. Y que decis que lo tengo que inicializar con NULL a lista?

Eternal Idol

http://www.cplusplus.com/reference/clibrary/cstdlib/realloc/

"ptr
    Pointer to a memory block previously allocated with malloc, calloc or realloc to be reallocated.
    If this is NULL, a new block is allocated and a pointer to it is returned by the function."

Ademas tendras que calcular correctamente el tamaño para ir agregando cada vez un elemento mas ...
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Ghalad

es que no hay que hacer calculos, es sencillo a vos te van a venir en varios strings, nose cuantos y lo que quiero hacer es: si me viene un string, reservo memoria para el puntero al string y reservo memoria para el string en si. Entonces no entiendo cual es el problema.

Código (cpp) [Seleccionar]
  lista = (char**)realloc(lista, sizeof(char*));
se supone que con eso cada vez que lo invoque genero una posicion mas de la lista de punteros


que tengo que hacer para que funcioneeeeeeeeee????? jajajja

Eternal Idol

Entonces el problema es que no entendes como funciona realloc, ya te deje el link antes:

"The size of the memory block pointed to by the ptr parameter is changed to the size bytes, expanding or reducing the amount of memory available in the block.
...
size
    New size for the memory block, in bytes.
    If it is 0 and ptr points to an existing block of memory, the memory block pointed by ptr is deallocated and a NULL pointer is returned."

Si llamas a realloc con el mismo tamaño al final de cuentas no estas haciendo nada logico, siempre reservas memoria para UN puntero en este caso, el segundo parametro de realloc es el tamaño TOTAL y no el tamaño a "agregar" por decirlo de algun modo.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Ghalad

#17
ahhh yo crei que vos le pasabas cuanto querias agrandar el bloque de memoria, entonces lo correcto seria algo asi:
Código (cpp) [Seleccionar]

char** obtenerLista(int *contador)
{
      int cont = 0;
      char buf[50], **lista = NULL;
     
      for(int i = 0; i < 10; i++)
      {
              printf("Ingresa cadena: ");
              fgets(buf, 50, stdin);
              buf[strlen(buf)-1] = '\0';
             
              if(strlen(buf) > 0){
                  ++cont;
                  lista = (char**)realloc(lista, sizeof(char*)*cont);
                  if(lista == NULL) abort();
                  lista[cont]= (char*)malloc( (sizeof(char)*strlen(buf))+1);
                  if(lista[cont]==NULL) abort();
                  strcpy(lista[cont], buf);
              }
      }
      *contador = cont;
      return lista;
}


De esta forma estaria diciendo que el puntero se agrande sizeof(char*) cada vez que quiero agregar un nuevo string?

Código (cpp) [Seleccionar]

char** obtenerLista(int *contador)
{
       int cont = 0;
       char buf[50], **lista = NULL;
       
       for(int i = 0; i < 10; i++)
       {
               printf("Ingresa cadena: ");
               fgets(buf, 50, stdin);
               buf[strlen(buf)-1] = '\0';
               
               if(strlen(buf) > 0){
                   ++cont;
                   lista = (char**)realloc(lista, sizeof(char*)*cont);
                   if(lista == NULL) abort();
                   lista[cont-1]= (char*)malloc( (sizeof(char)*strlen(buf))+1);
                   if(lista[cont-1]==NULL) abort();
                   strcpy(lista[cont-1], buf);
               }
       }
       *contador = cont;
       return lista;
}

con este codigo me funciones de 10! pero es correcto o e n que la estoy pifiando?

Eternal Idol

Si, pero cont arranca de 0 asi que:
lista = (char**)realloc(lista, sizeof(char*) * (cont+ 1));
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Ghalad

ahi le reste 1, funciona bien pero esta bien hecho el codigo? no estoy desperdiciando memoria en algun lado?