Duda Punteros Dobles/Array de punteros

Iniciado por MisterJava, 20 Diciembre 2012, 19:52 PM

0 Miembros y 1 Visitante están viendo este tema.

MisterJava

Buenas tardes.

Tenía una duda sobre la creación de Un array de punteros. Os explico la idea: Tengo que hacer un programa que me devuelva las lineas de entrada en orden inverso, es decir, la ultima linea como la primera, y la primera como la última. Para ello he recurrido a crear lo que viene siendo un puntero doble. Me he tirado toda la tarde intentando buscar una solucion pero no doy con ella, No se que estoy haciendo mal en el código y me sale un Segmentation Fault.

Aqui os muestro el código:

Citar
void delreves(FILE* archivo){
        char string[100];
        char *pointer;
        char **array_pointers;
        int i=0;
        char **aux;
        array_pointers=(char**)malloc(sizeof(char*));
        if(array_pointers==NULL){
                exit(-1);
        }
        int size=1;
        while(!feof(archivo)){
                fgets(string,2048,archivo);
        aux=(char **)realloc(array_pointers,(sizeof(char)*size));
        if(aux!=NULL){
                array_pointers=aux;
        }
        pointer=pointer+i;
        array_pointers=array_pointers+i;
        pointer=strdup(string);
        array_pointers=&pointer;
        size++;
        i++;
        }
}

El problema me surge principalmente al usar el movimiento de punteros, que no se porque no me lo ejecuta bien.

Os agradecería que me ayudarais a entender como usar un puntero doble para que vaya apuntando a cada uno de los punteros con malloc y realloc.

Gracias por vuestro tiempo.

rir3760

El problema principal en esa función es el incremento de la variable "array_pointers", al hacerlo pierdes la dirección base. En su lugar:

1) Reservas el bloque de memoria principal, este lo utilizas para almacenar la dirección de memoria de cada cadena.

2) Utilizas un auxiliar para leer la linea. Para esta reservas un bloque de memoria del tamaño apropiado, copias ahí la cadena y guardas su dirección en el bloque principal.

3) Si el bloque principal se llena reajustas su tamaño con realloc.

La función con las correcciones:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NUM_CHARS  4096

void delreves(FILE *entrada);

/* ... */

void delreves(FILE *entrada)
{
   char temp[NUM_CHARS];
   char **linea;
   int i;
   int max_lineas = 16;
   
   linea = malloc(max_lineas * sizeof *linea);
   
   i = 0;
   while (fgets(temp, NUM_CHARS, entrada) != NULL){
      linea[i] = malloc(strlen(temp) + 1);
      strcpy(linea[i], temp);
      i++;
     
      if (i == max_lineas){
         max_lineas *= 2;
         linea = realloc(linea, max_lineas * sizeof *linea);
      }
   }
   
   linea = realloc(linea, i * sizeof *linea);
   
   /* Procesamiento de las lineas ... */
   
   /* Liberacion de la memoria utilizada */
   while (i-- > 0)
      free(linea[i]);
   free(linea);
}

Por cierto no hay validaciones para reducir en lo posible el código fuente, eso te toca a ti.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

MisterJava

Cita de: rir3760 en 23 Diciembre 2012, 04:04 AM
El problema principal en esa función es el incremento de la variable "array_pointers", al hacerlo pierdes la dirección base. En su lugar:

1) Reservas el bloque de memoria principal, este lo utilizas para almacenar la dirección de memoria de cada cadena.

2) Utilizas un auxiliar para leer la linea. Para esta reservas un bloque de memoria del tamaño apropiado, copias ahí la cadena y guardas su dirección en el bloque principal.

3) Si el bloque principal se llena reajustas su tamaño con realloc.

La función con las correcciones:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NUM_CHARS  4096

void delreves(FILE *entrada);

/* ... */

void delreves(FILE *entrada)
{
   char temp[NUM_CHARS];
   char **linea;
   int i;
   int max_lineas = 16;
   
   linea = malloc(max_lineas * sizeof *linea);
   
   i = 0;
   while (fgets(temp, NUM_CHARS, entrada) != NULL){
      linea[i] = malloc(strlen(temp) + 1);
      strcpy(linea[i], temp);
      i++;
     
      if (i == max_lineas){
         max_lineas *= 2;
         linea = realloc(linea, max_lineas * sizeof *linea);
      }
   }
   
   linea = realloc(linea, i * sizeof *linea);
   
   /* Procesamiento de las lineas ... */
   
   /* Liberacion de la memoria utilizada */
   while (i-- > 0)
      free(linea[i]);
   free(linea);
}

Por cierto no hay validaciones para reducir en lo posible el código fuente, eso te toca a ti.

Un saludo

Tío, no sé como darte las gracias rir3760.
Esa forma de usar el realloc no se me había ocurrido y llevabamos pillados 1 semana(porque los profesores no explican una m...) y el usar el tamaño de p como contador de aumento de memoria ni me había fijado.

De verdad, GRACIAS! Te debo mi aprobado, puto crack. :)