Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: SARGE553413 en 22 Noviembre 2013, 16:05 pm



Título: Problema con memcpy() [SOLUCIONADO]
Publicado por: SARGE553413 en 22 Noviembre 2013, 16:05 pm
Hola a todos.

Tengo un vector de punteros a char.
Quiero leer todas las líneas de un fichero y almacenar cada una de ellas en cada componente de mi vector de punteros.
No conozco a priori el tamaño del fichero.

El problema es que, no se por qué, al redimensionar el vector de punteros voy perdiendo las cadenas almacenadas. Este es mi código:

Código:
#define readErr(ifs) ifs.rdstate() & ifstream::failbit

char ** readFich(ifstream &ifs,const int &BUFFER_S){
char line[BUFFER_S];
char **dev=new char*[1],**aux=NULL;
//dev = vector de strings donde almaceno cada linea del texto.
//aux = var. auxiliar para apuntar a dev mientras ésta es redimensionada.
int i=1;
//leo línea
ifs.getline(line,BUFFER_S);
        //la copio en el vector
        dev[i]=new char[BUFFER_S];
        strcpy(dev[i],line);
        while(!ifs.eof()){
        //Compruebo que no hay errores, si los hay, salgo del bucle.
        if (readErr(ifs)!= 0){
            cout<<"ERROR: INTENTANDO LEER MAS DE 256 CARACTERES"<<endl;
            break;
        }else{
            //libero la memoria a la que apuntaba aux
            delete[] aux;
            //salvo la direcc. de memoria de dev
            aux=dev;
            //redimensiono dev
            dev=new char*[i+1];
            //le paso los datos que tenia hasta ahora
            memcpy(dev,aux,sizeof(aux));
            //le asigno la nueva linea
            dev[i]=new char[BUFFER_S];
            strcpy(dev[i],line);
            //vuelvo a leer
            ifs.getline(line, BUFFER_S);
        }
        i++;
    }
    return dev;
}

No entiendo cual es el problema, ¿Qué puedo hacer?

Muchas gracias


Título: Re: Leer fichero y "trocearlo"
Publicado por: rir3760 en 22 Noviembre 2013, 18:29 pm
Tengo un vector de punteros a char.
Quiero leer todas las líneas de un fichero y almacenar cada una de ellas en cada componente de mi vector de punteros.
No conozco a priori el tamaño del fichero.

El problema es que, no se por qué, al redimensionar el vector de punteros voy perdiendo las cadenas almacenadas.
Cuando utilizas el operador new este reserva un bloque de memoria del tamaño apropiado, nada mas. El problema es que tu esperas que copie el contenido del bloque anterior y eso no lo hará el operador. Debes hacerlo manualmente reservando un nuevo bloque de memoria, copiando en el las direcciones de memoria y finalmente liberando el bloque original (y utilizando a partir de ese momento el nuevo bloque).

¿Qué puedo hacer?
Ya que el lenguaje es C++ es mejor utilizar un vector de objetos de tipo string para almacenar todas las lineas del archivo, con ello te liberas del manejo de memoria.

Un saludo


Título: Re: Leer fichero y "trocearlo"
Publicado por: SARGE553413 en 22 Noviembre 2013, 18:54 pm
Cuando utilizas el operador new este reserva un bloque de memoria del tamaño apropiado, nada mas. El problema es que tu esperas que copie el contenido del bloque anterior y eso no lo hará el operador. Debes hacerlo manualmente reservando un nuevo bloque de memoria, copiando en el las direcciones de memoria y finalmente liberando el bloque original (y utilizando a partir de ese momento el nuevo bloque).
Sí, lo sé, de hecho en el código que he escrito lo hago explicitamente con una variable auxiliar y memcpy(), por eso no entiendo que pasa.

Citar
Ya que el lenguaje es C++ es mejor utilizar un vector de objetos de tipo string para almacenar todas las lineas del archivo, con ello te liberas del manejo de memoria.
Cierto, pero esto no me lo permiten hacer usando la STL, tengo que manejar la memoria directamente. Además es algo que quiero entender como funciona.


Título: Re: Leer fichero y "trocearlo"
Publicado por: SARGE553413 en 22 Noviembre 2013, 19:08 pm
He estado haciendo mas pruebas y sustituyendo la parte del memcpy() por un bucle for todo funciona bien.

Código:
//Antes:
            //vuelvo a leer
            ifs.getline(line, BUFFER_S,'\n');
            //salvo la direcc. de memoria de dev
            aux=dev;
            //redimensiono dev
            dev=new char*[i+2];
            //le paso los datos que tenia hasta ahora
            memcpy(dev,aux,sizeof(aux));
            //le asigno la nueva linea
            dev[i]=new char[BUFFER_S];
            strcpy(dev[i],line);
            //libero la memoria a la que apuntaba aux
            delete[] aux;

//Después:
            //vuelvo a leer
            ifs.getline(line, BUFFER_S,'\n');
            //salvo la direcc. de memoria de dev
            aux=dev;
            //redimensiono dev
            dev=new char*[i+2];
            //le paso los datos que tenia hasta ahora
            for(int j=0;j<i;j++){
                dev[j]=aux[j];
            }
            //le asigno la nueva linea
            dev[i]=new char[BUFFER_S];
            strcpy(dev[i],line);
            //libero la memoria a la que apuntaba aux
            delete[] aux;

Algo pasa con el memcpy(), ¿Qué es?

Saludos


Título: Re: Leer fichero y "trocearlo"
Publicado por: SARGE553413 en 22 Noviembre 2013, 19:23 pm
Solución:

En la parte en la que se especifica sizeof() en memcpy, hay que multiplicarlo por la cantidad de chars (en este caso) que se quieren copiar.

Esto es porque si tienes un vector de 20 caracteres 'char c[20]', sizeof(c) devuelve 4 (tamaño del puntero a char, que es lo que es en realidad el vector) no devuelve los 20 chars que contiene.

Saludos.