[C con Clase] vector de string en c sin saber tamaño.

Steven Davidson srd4121 en njit.edu
Dom Abr 5 21:22:34 CEST 2009


Hola Agustín,

Agustin wrote:
> Hola David.
> Mil gracias por tomarte tu tiempo y la respuesta. Sería muy cómodo
> implementarlo de esa forma pero mi único problema es que quede con un
> compañero que le iba a pasar para que trabaje el comentario auto, un
> vector que en cada posición tenía una linea (le resultaba mejor por
> los tipos de cosas que tenía que levantar y demás) y cuando le
> comente lo de la lista me pidió que por favor no se lo cambie ahora
> poruqe iba a tener que cambiar todo lo que ya hizo.

Tienes algunos errores en cuanto al uso de memoria. Al tener un doble 
puntero y querer implementar una lista dinámica de cadenas de 
caracteres, necesitas crear memoria para 'array'. Como este array va a 
contener varios punteros, actuará como un directorio donde buscar cada 
cadena. Tendrás que ir creando memoria dinámicamente para agregar cada 
puntero. Por ejemplo,

/* Al principio */
int nCadenas = 0;
char **array;
...
array = (char *) malloc( sizeof(char *) );  /* Para 1 cadena en total */
nCadenas++;

Aconsejo mantener la cantidad de cadenas que vas a ir agregando.

Al agregar una cadena, creamos memoria dinámicamente y agregamos la 
dirección de memoria al último elemento de nuestro "directorio". Esto es,

array[nCadenas-1] = (char *) malloc( tam_linea );

Recuerda que 'char' siempre ocupa 1 byte, por lo que no es necesario 
"preguntar" con 'sizeof'.

Luego, escribes lo siguiente:

*array+j = linea;

Si quieres copiar una cadena a otra, debes copiar su contenido. En la 
sentencia anterior simplemente copias la dirección de memoria contenida 
en 'linea'. Sugiero usar 'strcpy()'. Si sabes la cantidad de caracteres, 
entonces puedes usar 'memcpy()' para optimizar el tiempo de ejecución.

Otro matiz a comentar es usar 'realloc()' al agregar una cadena a 
'array'. Esta función redimensiona el array sin eliminar la información 
contenida previamente si el tamaño es aumentado. Por ejemplo,

array = (char *) realloc( ++nCadenas * sizeof(char *) );

Al agregar más memoria a la que teníamos antes, no perdemos la 
información "antigua". Es una gran ventaja al usar 'realloc()'.


Puedes hacer todo esto con 'realloc()' y 'malloc()', pero según el 
problema que estás intentando solucionar, sugiero usar listas 
dinámicamente enlazadas (o ligadas). De esta forma, no tienes que ir 
readjudicando memoria, sino que simplemente creas memoria justo para los 
datos que quieres agregar. Esto funciona en base a "nodos", y cada nodo 
contiene la información que te interesa además de un puntero al 
siguiente nodo; he aquí el enlace o liga, como un eslabón en una cadena. 
Puedes consultar el primer capítulo de nuestro curso de "Estructuras 
Dinámicas de Datos" yendo a: http://c.conclase.net/edd/index.php


Espero que todo esto te ayude.

Steven





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