2010-09-08 21 views
11
// Assume class definition for Cat is here. 

Cat makeCat() { 
    Cat lady = new Cat("fluffy"); 
    return lady; 
} 

int main (...) { 
    Cat molly = makeCat(); 
    molly->eatFood(); 
    return 0; 
} 

Habrá un "uso después de liberación" error en molly->eatFood()?C++ - función que devuelve objeto

+0

En el ejemplo falta el tipo de devolución para makeCat(). – pascal

+0

Y tiene más errores. Si desea saber acerca de un error en tiempo de compilación, al menos debe publicar código compilable. – sbi

+2

Kevin: lee sobre STL auto_ptr y aumenta shared_ptr. –

Respuesta

19

ha corregido su programa y crearon un ejemplo de implementación class Cat:

#include <iostream> 
#include <string> 

class Cat { 
public: 
     Cat(const std::string& name_ = "Kitty") 
     : name(name_) 
     { 
       std::cout << "Cat " << name << " created." << std::endl; 
     } 
     ~Cat(){ 
       std::cout << "Cat " << name << " destroyed." << std::endl; 
     } 
     void eatFood(){ 
       std::cout << "Food eaten by cat named " << name << "." << std::endl; 
     } 
private: 
     std::string name; 
}; 

Cat* makeCat1() { 
     return new Cat("Cat1"); 
} 

Cat makeCat2() { 
     return Cat("Cat2"); 
} 

int main(){ 
     Cat kit = makeCat2(); 
     kit.eatFood(); 

     Cat *molly = makeCat1(); 
     molly->eatFood(); 
     delete molly; 

     return 0; 
} 

Se producirá la salida:

Cat Cat2 created. 
Food eaten by cat named Cat2. 
Cat Cat1 created. 
Food eaten by cat named Cat1. 
Cat Cat1 destroyed. 
Cat Cat2 destroyed. 

le sugiero que aprender un libro básica sobre el C++ principio a fin antes de continuar .

+0

gracias, Notinlist. –

+3

... aunque puede producir un resultado diferente ya que el estándar C++ no requiere un compilador para elide copias innecesarias siempre que sea posible. Por lo tanto, es completamente posible ver otros dos mensajes "Gato Cat2 destruido" (sin RVO, por ejemplo) – sellibitze

+0

'makeCat1' devuelve un puntero, y' makeCat2' devuelve una referencia? – qed

3

No hay ningún error en cuanto al uso no válido de memoria que no sea una pérdida de memoria al final de su programa. Si se crea algo en el montón (como con new), entonces necesita llamar al delete para liberarlo.

También tiene un montón de errores de sintaxis, corregidos a continuación.

Cat* makeCat() 
{ 
    Cat *lady = new Cat("fluffy"); 
    return lady; 
} 

int main (int argc, char** argv) 
{ 

    Cat* molly = makeCat(); 
    molly->eatFood(); 

    delete molly;//This was added 
    return 0; 
} 
+0

¿Se puede perder memoria cuando finaliza el programa? – Eiko

+0

@Eiko: por lo general, el sistema operativo lo liberará, pero esto no está garantizado. Para cualquier cosa que no esté garantizada, es altamente desaconsejado hacerlo. Especialmente con no liberar memoria. Por ejemplo, quien dice que una parte importante del código no existe en el destructor. –

+0

Estoy de acuerdo en que es aconsejable limpiarlo después de usted, y con el código limpio no es mucho trabajo de todos modos. (Aunque a veces leo los consejos para no perder esos ciclos de CPU) – Eiko

0

creo que debe ser Cat *lady y Cat *molly, pero de lo contrario debería estar bien.

+0

Cuando devuelvo el objeto ** sally **, ¿no es ese valor por pasaporte? En caso afirmativo, ¿** ** sally ** no se eliminará después de que termine la función? –

+0

Si con 'sally' te refieres a la variable 'lady' dentro de makeCat, no. – MerickOWA

+0

En realidad, pasa un puntero (pero omitió el "*" en su código. – Eiko

2

Dado que lady se crea en el montón (con un new), no se destruirá cuando salga del método makeCat. Entonces la llamada en molly es perfectamente válida.

PERO, tiene una pérdida de memoria. Debe eliminar molly después de usarlo (en el futuro). Ya que su programa finaliza, esto no es un gran problema. En un programa más grande, esto sería un gran problema.

5

new Cat("fluffy") crea un puntero. Tendrá que especificar Cat* como tipo de devolución. Como el objeto se crea en el montón, seguirá estando disponible después de que se devuelva la función.

+0

Todavía está disponible cuando se crea en la pila como se devuelve por valor (es decir, copia reconstruida (aunque el compilador puede eludir la copia)). Aparte del error de sintaxis, el código está bien tal como está escrito y no utiliza un objeto destruido. –

2

El problema no es un "uso después de gratis"; más probablemente, no estás eliminando la nueva instancia.

0

Si su compilador compatible con C++ 11 puede utilizar unique_ptr aquí:

#include <iostream> 
#include <memory> 

using namespace std; 
class Cat { 
    public: 
     Cat() { 
      cout << "Cat created" << endl; 
     } 
     ~Cat() { 
      cout << "Cat destroyed" << endl; 
     } 
     void eatFood() { 
      cout << "Cat is eating food" << endl; 
     } 
}; 

unique_ptr<Cat> makeCat() { 
    unique_ptr<Cat> lady(new Cat); 
    return lady; 
} 

int main() { 
    unique_ptr<Cat> molly = makeCat(); 
    molly->eatFood(); 
    return 0; 
} 

Ahora, usted no tiene que preocuparse acerca de cómo eliminar objeto creado. Se eliminará tan pronto como el puntero molly salga del alcance:

Cat created 
Cat is eating food 
Cat destroyed 
Cuestiones relacionadas