C/Visual C - Devolver cadena por parametro despues de MALLOC

 
Vista:

Devolver cadena por parametro despues de MALLOC

Publicado por LEONE (10 intervenciones) el 18/03/2002 14:04:28
Mi duda es la siguiente, la cabecera de el procedimiento que tengo hecho en C es la siguiente: void leercad(char *cad, int max, int solonum), donde max es un parámetro que dice la longitud máxima y solonum si solo se pueden introducir números desde teclado. Mi duda es que despues de hacer un malloc a la cadena con el tamaño máximo, la dirección de inicio de la cadena cambia, y entonces, cuando se vuelve al procedimiento que llamó la cadena está apuntando a otro sitio, ¿cómo se soluciona esto?, lo normal es llamarlo leercad(cadena,20,0) donde cadena se ha declarado como char *cadena. ¿Qué es lo que está mal, como consigo q devuelva por parámetro la dirección correcta? Ya sé que la función es muy simple si se hace devolviendo un char*, pero es que me gusta más en este caso devolverlo por parámetro y no por función, y ya de paso, aprender algo más. Gracias
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Devolver cadena por parametro despues de MALLOC

Publicado por Alvaro (122 intervenciones) el 19/03/2002 00:29:55
De hecho, al hacer malloc dentro del procedimiento, estas cambiando la dirección de memoria que habia al principio en 'cadena' (eso es lo que hace malloc).
Si quieres utilizar malloc en el procedimiento, 'cadena' debe ser siempre de tipo char *. Con esto estarias pasando solo un puntero a char al procedimiento y luego recibiendo un espacio de memoria ya asignado. Esto implica que al final debes preocuparte por liberar esa memorio con free.
por ejemplo:

#define MAX nnn
...
...
char *cadena; //es un puntero a char
leercad(cadena, MAX, 0);
hacer_algo_con_cadena(cadena);
free(cadena);
...
antes de llamar a leercad, cadena tiene cualquier valor (apunta a cualquier parte de la memoria). dentro de leercad se utilizo malloc, por lo que ahora tiene una direccion de memoria que es valida. (y la has reservado por lo que debes liberarla cuando no sea útil)
si quieres definir 'cadena' como
char cadena[N];
para hacer algo con ella antes de llamar al procedimiento no debes usar malloc dentro del procedimiento.
recuerda que una variable del tipo 'char a[N]' sigue siendo un puntero a memoria.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Devolver cadena por parametro despues de MALLOC

Publicado por LEONE (10 intervenciones) el 19/03/2002 14:54:39
El problema está en que una vez se vuelve al procedimiento q lo llamó, cadena sigue apuntando donde al principio, y el malloc de leercad ha cambiado la dirección, pero de la variable de el procedimiento, no de 'cadena', por eso apunta a un valor no reservado por malloc.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Devolver cadena por parametro despues de MALLOC

Publicado por Josep (29 intervenciones) el 19/03/2002 20:57:51
He estado mirando tu duda y me parece muy interesante (recordando viejos tiempos jeje). Tal y como has dicho este problema se soluciona transformando la acción en función.

El problema viene en qué estas pasando la cadena por referencia. Pero tu no quieres devolver el contenido de la cadena, quieres devolver el puntero. A ver si me explico: todos los paràmetros que se pasan en una funcion/acción (en C) son por valor pero cuando quiere modificar alguno le pasas su dirección de memoria (puntero) para poder modificar su contenido. Fijate que le pasas la dirección (puntero) por valor -> no podras modificar la dirección pero sí su contenido!!

Entonces una solución podria ser esta: puntero de puntero a un char. Con código se entiende mejor creo:

char *pCadena;
leerCad(&pCadena, 20, 0);

La declaración de leerCad quedaria asi:
void leerCad(char **ppCadena, int iMax, int iSolonum)
{
*ppCadena=malloc(sizeof(char)*iMax);
...
}

Todo esto aun no lo he probado, te lo he dicho basandome en la teoria.
Respondeme a ver cómo te ha ido.
Espero que te haya ayudado en tu pregunta.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Devolver cadena por parametro despues de MALLOC

Publicado por LEONE (10 intervenciones) el 20/03/2002 15:57:37
Pues aún no lo he probado, lo haré ahora, pero realmente lo que quiero hacer es un 'gets', es decir, no tener que usar en la llamada * mi &, simplemente, pasarle un *char, es decir, creo q la solución es guardar antes de hacer el malloc y dentro de el procedimiento la dirección inicial de 'cadena', y luego, modificarla de alguna manera para que al salir cadena ya apunte al principio de la memoria reservada de la cadena, claro, ésto, para que sea totalmemte transparente desde fuera ha de hacerse dentro del procedimiento.

Gracias.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Devolver cadena por parametro despues de MALLOC

Publicado por LEONE (10 intervenciones) el 20/03/2002 16:04:04
Pues no funciona, el parámetro q se le pasa no es del mismo tipo, ** y *, pero creo q la cuestión es esa q he dicho, saber la dirección del puntero cadena, y luego, esa misma dirección se cambia a donde apunta despues de haberse hecho el malloc, supongo q será parecido a lo que hace un gets.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Devolver cadena por parametro despues de MALLOC

Publicado por Josep (29 intervenciones) el 20/03/2002 20:20:43
He probado lo que yo decia y me ha funcionado ... He probado este código de función y parece que no da error:

void leerCad(char **pChar, int iMax)
{
int i;
char* pCad;
pCad=(char*)malloc(sizeof(char)*iMax);
*pChar=pCad;
// inicializar *pChar (pCad) todas las posiciones con 'a'.
for(i=0; i<iMax-1; i++)
pCad[i]='a';
pCad[i]='\0';
}

luego al ejecutar la sentencia:

char * pChar;
leerCad(&pChar,20);
printf("%s",pChar);

devuelve 20 a's tal y como está indicado en la función.

Te he mandado por email el codigo fuente por si acaso,
espero haberte ayudado en algo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar