Duda como devolver char* en c++

Z

Tengo una función que devuelve un char* pero no se cual seria la manera mas correcta de hacerlo

const char* Fecha::cadena()const{
	
  ....//lo de aqui no es necesario
    
char* cad =new char[100];

     ....//lo de aqui tampoco
return  cad;
}

Si lo hago así estoy reservando memoria que no libero nunca .

Y si lo hago asi

const char* Fecha::cadena()const{
	
  ....//lodeaqui no es necesario
    
char cad[100];

     ....//lo deaqui tampoco
return  cad;
}

Devolvería la direccion de una variable local por lo que tendría un warning y posiblemente algún error en tiempo ejecución, como lo debería hacer?

gonya707

porque al devolver una variable local vas a tener un warning?

las dos formas son equivalentes, vas a reservanr en las dos 100 bytes, ni mas ni menos, que puedes liberar de la memoria cuando te apetezca.

por cierto, mis profesores me dijeron que usar const es una costumbre de malos programadores (en ansi C ni existe). Si no quieres que se modifique el valor de algo, pues se consciente de lo que estas haciendo y no lo modifiques, dejar ahi los const dolo va a servir para que te lleves errores y warnings

3 respuestas
cabron

#1

Lo que no puedes devolver es la dirección de memoria de una variable local, por que se libera después de terminar la función, pero no hay ningún problema en devolver su valor.

En este caso al ser un puntero, el valor es una dirección de memoria, pero esa dirección de memoria es el contenido del puntero no la dirección de la variable.

#2

const sí que existe en C++, si estás programando en C++ es irrelevante que no exista en C

1 respuesta
gonya707

#3 ya se que si existe en C++...

1 respuesta
cabron

#4

A lo mejor te entendí mal pero parecía que usabas como argumento para no usar const que no está en C, algo irrelevante por que no es el mismo lenguaje, sin contar que C es bastante más antiguo y había practicas de programación que todavía no existían, por esa regla de 3 podríamos decir que está mal usar clases por que C no las tiene.

Y sobre la recomendación de tus profesores, pues bueno, que cada uno programe como le de la gana, pero me parece una chorrada y en casi cualquier sitio te van a recomendar que uses const.

Si sigues la recomendación de tus profesores, declara todo tus punteros como void, ya que un programador responsable no necesita tipos de datos, que sea consciente siempre de lo que está haciendo.

Z

Esto funciona perfectamente ..


const char* Fecha::cadena()const{
       
      ....//lo de aqui no es necesario
       
        char* cad =new char[100];
       
         ....//lo de aqui tampoco
        return  cad;
}

Pero reservo con el new pero no hay delete..eso se queda reservado y no se libera...y eso como que a los profesores no les gusta

y si lo hago sin reservar memoria(al menos explícitamente)

    const char* Fecha::cadena()const{
           
....//lodeaqui no es necesario char cad[100]; ....//lo deaqui tampoco return cad; }

El compilador me dice, " warning: address of local variable ‘cad’ returned [-Wreturn-local-addr]
char cad[100];
"
Básicamente lo que me preocupa es el new sin delete ,por lo que dije antes..a los profesores eso...

1 respuesta
cabron

#6

Es que si haces lo segundo la memoria para el array 'cad' se reserva en la pila, y se libera al terminar la función, así que básicamente estás devolviendo un puntero a una zona de la pila que más adelante va a estar ocupada por dios sabe qué y puedes hacer un destrozo bueno si te pones a usar el contenido de esa memoria.

Sobre lo de new/delete es más complejo que eso, es obvio que tienes que hacer delete en algún momento, pero no tiene por que ser en el mismo sitio (por ejemplo RAII usa el destructor de la clase para hacer delete), pero si lo que te preocupa es aprobar hazlo de la forma en la que te digan.

¿No has pensado en declarar ese array como un simple miembro de la clase Fecha? Así no tienes que declararla como variable local dentro de una función.

2 respuestas
Z

#7
Precisamente ese es el problema que no quiero probar nada demasiado "creativo",como añadirmienmbrso que no se piden , no vaya a ser que no le guste al que corrige.

B

#2 la primerísima vez que leo en mi vida que usar const es una mala costumbre, flipo bastante con que haya gente que diga eso y esté enseñando nada a nadie.

r2d2rigo

#2 cambia de profesores ya. En C++ es good practice marcar como const reference todos los parametros que puedas, para evitar al mismo tiempo copias de valores y modificaciones accidentales.

#7 no tienes alternativa, si haces new en la funcion vas a tener que hacer un delete al resultado despues de llamarlo. Otra cosa que puedes hacer es cachear el resultado como miembro privado de la funcion y liberarlo en el destructor:

private:
char* fechaAsCadena;

const char* Fecha::cadena()const
{
    if (fechaAsCadena != NULL)
    {
        delete fechaAsCadena;
        fechaAsCadena = NULL;
    } 

fechaAsCadena = new char[100];
// Formatear fecha en fechaAsCadena...

return fechaAsCadena;
}

Fecha::~Fecha()
{
    if (fechaAsCadena != NULL)
    {
        delete fechaAsCadena;
        fechaAsCadena = NULL;
    } 
}

Usuarios habituales