Hola comunidad tengo dificultades con las funciones al retornar un puntero a char o asignandolos a un doble puntero pasado por parametro. ¿Si uno declara una cadena en una funcion y quiere llevarla a main, si un puntero toma esa cadena se desapila igual?
Depende de cómo se haya declarado esa cadena.
Si es memoria dinámica, obtenida con malloc o new en C++, puedes devolverla (recordando que habrá que liberarla posteriormente).
Si hablamos de C++, y son cadenas de tipo std:.string o en general, un std::vector o cualquier otra clase del estilo, podrás retornarla sin problemas.
Estoy trabajando en ANSI C , y realmente andar devolviendo cadenas dinamicas cada vez que le pido al usuario es muy molesto, no hay alguna forma de no usar memoria dinamica? Por que tengo una funcion que parsea y no carga memoria dinamica a una estructura, si yo luego quiero cargar mas cadenas a la estructura las cargaria dinamicas y tendria que liberar algunas.... Se vuelve loco uno si anda devolviendo punteros dinamicos a cada rato y encima se mezclan cpn punteros estaticos.. Debe haber alguna manera en C de poder devolver cadenas
no lo hay, justo el punto para el que se usa C es para tener mucho control a bajo nivel y en el control de asignación de memoria, el string no es un tipo, el string no es más que un array de char y ha de ser manejado como tal
Para retornar un puntero a char no queda otra que usar memoria dinamica?
Otra opción, y véase que esta tiene sus contras, es tenes un array static en la función:
char* func(){
static char arr[50];
arr[0] = 'H';
arr[1] = 'o';
arr[2] = 'l';
arr[3] = 'a';
arr[4] = '\0';
return arr;
}
Una variable static en una función no va a liberarse cuando la función haya retornado, así que puedes retornar su dirección de memoria sin problema.
Si hicieras esto con memoria dinámica, tendrías que recordar el liberarla entre llamadas, o cuando fuera necesario,
Si tan molesto es usa una cadena global como dato auxiliar. En la función lo cargas con la respuesta del usuario y una vez que regrese copias la información que hay en el buffer que te interese.
O pasas como parámetro el buffer de interés a la función y que esta solo se encargue de llenarlo.
Hay más formas conseguir una cadena en una función y retornarla después.
Como ya te han dicho antes, en c no hay tipo de datos string, luego solo queda trabajar con arreglos de chars (lo que viene siendo la propia imp!ementacion del tipo string). Ahora, si intentas devolver una variable local en una funcion los datos retornados seran inconsistentes e impredecibles ya que dicha variable local al salir de su ambito (funcion) sera eliminada del stack. Para lograr lo que quieres tienes un par de opciones:
1- Creas la variable en la funcion padre y la pasas como parametro por referencia
2- Usas variables globales, estáticas o memoria dinamica (como dijeron antes tienes que estar seguro de eliminarla cuando no la necesites)
3- Haces una copia de la variable retornada justo al salir de la funcion:
Si es una cadena puedes usar strcpy, strncpy, etc. Para cualquier otro tipo de datos memcpy, copy, etc
char mystr[MAX_PATH];
char *ptr = MyFunction();
if(ptr != null)
// evita bof
strncpy(mystr, ptr, sizeof(mystr));
BONUS- Si trabajar estrictamente con char* no es un requisito entonces usa std::string al retornar de la funcion:
std::string mystr = MyFunction();
Saludos
Cita de: ThunderCls en 26 Junio 2018, 16:41 PM
BONUS- Si trabajar estrictamente con char* no es un requisito entonces usa std::string al retornar de la funcion:
std::string mystr = MyFunction();
Pero eso no funciona en C.
Cita de: srWhiteSkull en 26 Junio 2018, 18:38 PM
Pero eso no funciona en C.
Nope por eso esta tachado ;)
Cita de: ThunderCls en 26 Junio 2018, 16:41 PM
Como ya te han dicho antes, en c no hay tipo de datos string, luego solo queda trabajar con arreglos de chars (lo que viene siendo la propia imp!ementacion del tipo string). Ahora, si intentas devolver una variable local en una funcion los datos retornados seran inconsistentes e impredecibles ya que dicha variable local al salir de su ambito (funcion) sera eliminada del stack. Para lograr lo que quieres tienes un par de opciones:
1- Creas la variable en la funcion padre y la pasas como parametro por referencia
2- Usas variables globales, estáticas o memoria dinamica (como dijeron antes tienes que estar seguro de eliminarla cuando no la necesites)
3- Haces una copia de la variable retornada justo al salir de la funcion:
Si es una cadena puedes usar strcpy, strncpy, etc. Para cualquier otro tipo de datos memcpy, copy, etc
char mystr[MAX_PATH];
char *ptr = MyFunction();
if(ptr != null)
// evita bof
strncpy(mystr, ptr, sizeof(mystr));
BONUS- Si trabajar estrictamente con char* no es un requisito entonces usa std::string al retornar de la funcion:
std::string mystr = MyFunction();
Saludos
Podrias mostrar un ejemplo mas detallado de la opcion 3 por favor?
Para la opcion 3 ya te he puesto un codigo de ejemplo, la funcion MyFunction() es simplemente cualquier funcion que manipule un arreglo de chars local y lo devuelva:
char * MyFunction()
{
char mystr[255] = "Hello\0";
return mystr;
}