elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  punteros como parametros de funciones que no retornan nada... buena idea?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: punteros como parametros de funciones que no retornan nada... buena idea?  (Leído 2,458 veces)
digimikeh

Desconectado Desconectado

Mensajes: 191


Ver Perfil
punteros como parametros de funciones que no retornan nada... buena idea?
« en: 23 Febrero 2019, 16:08 pm »

Según he venido entendiendo hasta ahora, si yo creo un puntero, éste intenta localizar memoria en el espacio dinamico…. estos espacios de memoria deben ser liberados, pero que pasa en el siguiente caso?

Código
  1. void Persona::IngresarNombre(const char * nombre){
  2.     strcpy(this->nombre, nombre);
  3.  
  4.     delete nombre;   //Es esto necesario?
  5. }
  6.  


Que sucede con ese puntero a char que está como parámetro?, se elimina solo o yo debo eliminarlo también?

o es mejor idea esto?:

Código
  1. void Persona::IngresarNombre(const char nombre[16]){
  2.     strcpy(this->nombre, nombre);
  3. }
  4.  
Gracias.


En línea

Dungeons & dragons;
dragons.Attack();
K-YreX
Moderador
***
Desconectado Desconectado

Mensajes: 1.008



Ver Perfil
Re: punteros como parametros de funciones que no retornan nada... buena idea?
« Respuesta #1 en: 23 Febrero 2019, 16:25 pm »

Las dos opciones que tienes son:
Código
  1. void Persona::IngresarNombre(const char *nombre);
  2.  
  3. void Persona::IngresarNombre(const char nombre[]);

Y en ambos casos estás haciendo lo mismo. Estás pasando como parámetro la dirección del elemento 0, es decir, el inicio del array en este caso (ya que doy por hecho que ese puntero contiene una cadena/array de caracteres).

No tienes que liberarlo; y te explico. Un puntero se libera con <delete> si se ha usado antes <new> sobre él. Es decir, sólo si estás usando memoria dinámica. En otro caso el puntero se libera solo cuando finaliza la ejecución del programa como cualquier otra variable.
En el caso de que SÍ estés usando memoria dinámica, debes liberar el puntero cuando ya no vayas a usarlo más. Y si has asignado el valor de ese puntero a otro puntero y borras el primero, también estarás borrando el segundo. Ya que lo que haces en realidad es liberar la memoria a la que está apuntando.

Mi recomendación es que no borres el puntero dentro de la función y así te servirá para pasar punteros dinámicos como no dinámicos. Si dentro de la función borras el puntero y en un caso determinado le pasas un puntero no dinámico (osea el comienzo de un array creado sin <new>) tendrás problemas.

Te dejo aquí un par de ejemplos simples para que veas las diferencias :-X:
Código
  1. int main(){
  2.    char *p_dinamico;
  3.    p_dinamico = new char [20]; // tendras que liberarlo antes de acabar la ejecucion del programa
  4.    char p_estatico[20]; // se liberara solo al acabar
  5.  
  6.    Persona my_person;
  7.    my_person.InsertarNombre(p_dinamico); // p_dinamico lo puedes liberar en el main mas adelante
  8.    my_person.InsertarNombre(p_estatico); // p_estatico se liberara solo
  9.  
  10.    delete [] p_dinamico; // como hemos dicho antes
  11. }


En línea

Código
  1. cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
avesudra


Desconectado Desconectado

Mensajes: 724


Intentando ser mejor cada día :)


Ver Perfil
Re: punteros como parametros de funciones que no retornan nada... buena idea?
« Respuesta #2 en: 23 Febrero 2019, 16:34 pm »

[EDITO] : No había visto el post de YreX-DwX  :-(

Hola digimikeh,

Todo depende de cómo haya sido reservada la memoria a la que apunta el puntero "nombre". Tienes dos casos:

  • Que fuera reservada dinámicamente con new, en tal caso, debería liberarse en algún sitio, pero no necesariamente ahí.
  • Que fuera reservada estáticamente, en tal caso no es necesario que se libere. Un ejemplo podría ser un literal como:
Código
  1. const char* cadena = "hola"

    En éste último caso la duración de esa memoria será hasta el fin de la ejecución de tu programa y no es necesario que la liberes.

    Un ejemplo de ambos casos sería(fíjate que cadenaB se libera porque se reservó con new):
    Código
    1. const char* cadenaA = "HOLA";
    2. char* cadenaB = new char[5];
    3. strncpy(cadenaB, cadenaA, 5);
    4.  
    5. Persona personaA = new Persona();
    6. Persona personaB = new Persona();
    7.  
    8. personaA.IngresarNombre(cadenaA);
    9.  
    10. personaB.IngresarNombre(cadenaB);
    11.  
    12. delete[] cadenaB;
    13.  

    Saludos.
    « Última modificación: 23 Febrero 2019, 16:36 pm por avesudra » En línea

    Regístrate en
    K-YreX
    Moderador
    ***
    Desconectado Desconectado

    Mensajes: 1.008



    Ver Perfil
    Re: punteros como parametros de funciones que no retornan nada... buena idea?
    « Respuesta #3 en: 23 Febrero 2019, 16:58 pm »

    Código
    1. const char* cadenaA = "HOLA";
    2. char* cadenaB = new char[5];
    3. strncpy(cadenaB, cadenaA, 5);
    4.  
    5. Persona personaA = new Persona();
    6. Persona personaB = new Persona();
    7.  
    8. personaA.IngresarNombre(cadenaA);
    9.  
    10. personaB.IngresarNombre(cadenaB);
    11.  
    12. delete[] cadenaB;
    13.  

    Un pequeño apunte. Los objetos de tipo persona los estás creando dinámicamente:
    Código
    1. Persona *personaA = new Persona();
    2. Persona *personaB = new Persona();
    3. // ...
    4. delete personaA;
    5. delete personaB;

    Si los creas estáticamente no necesitas usar <new>:
    Código
    1. Persona personaA; // ya llama al constructor sin parametros sin especificarlo nosotros
    2. // ...
    3. // no es necesario liberar memoria ya que no se ha reservado memoria dinamicamente
    En línea

    Código
    1. cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
    avesudra


    Desconectado Desconectado

    Mensajes: 724


    Intentando ser mejor cada día :)


    Ver Perfil
    Re: punteros como parametros de funciones que no retornan nada... buena idea?
    « Respuesta #4 en: 23 Febrero 2019, 18:42 pm »

    Un pequeño apunte. Los objetos de tipo persona los estás creando dinámicamente:
    Código
    1. Persona *personaA = new Persona();
    2. Persona *personaB = new Persona();
    3. // ...
    4. delete personaA;
    5. delete personaB;

    Si los creas estáticamente no necesitas usar <new>:
    Código
    1. Persona personaA; // ya llama al constructor sin parametros sin especificarlo nosotros
    2. // ...
    3. // no es necesario liberar memoria ya que no se ha reservado memoria dinamicamente

    Cierto, se me ha pasado, el copy-paste....

    Muchas gracias y saludos.
    En línea

    Regístrate en
    digimikeh

    Desconectado Desconectado

    Mensajes: 191


    Ver Perfil
    Re: punteros como parametros de funciones que no retornan nada... buena idea?
    « Respuesta #5 en: 23 Febrero 2019, 20:10 pm »

    Gracias, hombre, estoy aprendiendo muy rápido en este foro.
    En línea

    Dungeons & dragons;
    dragons.Attack();
    Loretz

    Desconectado Desconectado

    Mensajes: 117


    Ver Perfil
    Re: punteros como parametros de funciones que no retornan nada... buena idea?
    « Respuesta #6 en: 24 Febrero 2019, 02:36 am »

    Pregunta:
    Es esto necesario?

    Citar
    void Persona::IngresarNombre(const char * nombre){
         strcpy(this->nombre, nombre);
     
         delete nombre;   //Es esto necesario?
    }

    Respuesta:
    ¿Cómo saberlo?

    Se podría intentar responder primero a algunas cuestiones preliminares, por ejemplo:

    ¿Está claro en la documentación de cada función que invoca a IngresarNombre() que este parámetro va a ser destruido (delete) (y que cualquiera que vaya a usarla jure primero no volver a usar ese puntero después del punto de llamada).

    Este puntero "nombre" ¿fue creado con new? ¿Seguro? (¿no habrá sido con malloc?)

    ¿No convendría llamar a esta función de alguna manera que deje más claro su comportamiento, por ejemplo,  IngresarNombreYCuidadoQueAcaMuereElPunteroNombre() ?

    Cuando una función recibe un puntero "final", se dice que esa función recibe el "ownership", la responsabilidad del "delete", y se la suele llamar "sink function".

    Ejemplo:

    Código:
    void sink_f(const char* p) // ¡¡ATENCIÓN!! ESTA FUNCIÓN DESTRUIRÁ A p ¡¡CUIDADO!! ¡¡ALERTA!!
    {
        // hacer algo con p, y después
        delete[] p;
    }

    Y una forma de llamarla sería:

    Código:
    int main() 
    {
        char* str = new char[12];
        strcpy(str, "hola mundo!");
        sink_f(str);
        // delete[] str; // QUÉ SUERTE QUE LEÍ EL COMENTARIO DE sink_f(), uffff!!

    }


    Francamente... ¿qué opinas?

    Por suerte ya nadie hace cosas como esa, espero.

    En línea

    Páginas: [1] Ir Arriba Respuesta Imprimir 

    Ir a:  

    WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines