[C con Clase] si, esta bien, stl, ¿es la única manera?

Steven Davidson steven en conclase.net
Lun Ene 15 15:17:02 CET 2007


Hola Reinel,

El pasado 2007-01-15 13:36:36, Rey escribió:
 
R> Gracias Stevens por la ayuda, entiendo eso, bueno, lo entiendo pero no lo he usado, es decir, las stl. Peor la duda mia es saber si se puede hacer algo parecido a esto:
R> 
R> char **ListaNombres;
R> 
R> y simplemente luego ir haciendo algo parecido a ListaNombres[0] = “Fulano de tal”;
R> 
R> etc.
R> 
R> Porque si es posible hacer algo así:
R> 
R> char *Nombre;
R> 
R> gets(Nombre);
R> 
R> creo que quizás pueda hacerse algo parecido a char **ListaNombres, es decir, un arreglo de cadenas donde no es necesario específicar el tamaño que tendrá cada cadena, porque es precisamente un puntero a char.
R> 

No es correcto declarar un puntero e inmediatamente copiar datos a partir de la dirección de memoria que guarda. En primer lugar, porque 'Nombre' no ha sido ni inicializado ni asignado un valor inicial y por tanto contiene basura. Ahora mismo 'Nombre' puede estar apuntando a la memoria para gráficos, al sistema operativo, o incluso a tu propio programa. En cuanto empieces a escribir datos a partir de esa dirección de memoria, sobreescribirás la información que existe. Lo más seguro es que el sistema operativo te dé un error durante la ejecución de tu programa. En segundo lugar, aunque supieras que 'Nombre' apunta a una dirección de memoria válida, el sistema no te redimensiona la cantidad de memoria que necesitas a medida que vayas guardando datos.

Debes eliminarte de la cabeza estas dos ideas:
1. No se redimensiona automáticamente la memoria para hacerla "crecer" ni "reducir" a nuestra medida, y
2. Al usar punteros, debemos dar valores válidos.


Si no quieres usar las STL, entonces como ya te dije en el mensaje anterior, tendrás que implementar una estructura dinámica de datos. Por ejemplo, una lista dinámicamente enlazada para representar varias cadenas de caracteres. Para representar una cadena de caracteres redimensionable, tendrás que hacer algunos malabarismos con la memoria. Por ejemplo,

char *szCadena = new char[128];
...
// Redimensionar la cadena
char *aux = new char[128+32];  // Agregamos 32 caracteres más
memcpy( aux, szCadena, 128 );
delete[] szCadena;
szCadena = aux;

Usamos el puntero 'aux' para crear una nueva cadena de mayor tamaño que 'szCadena', y copiamos la información a 'aux'. Ya no necesitamos la memoria apuntada por 'szCadena', por lo que la borramos. Sin embargo, nos interesa continuar usando el puntero llamado 'szCadena', por lo que luego copiamos esa dirección de memoria a 'szCadena'.

Tendrías que hacer algo parecido a esto, que de hecho la clase 'string' lo implementa así.


Espero haber aclarado el asunto.

Steven


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