2010-08-11 12 views
9

Debajo del código esperado para imprimir "kevin" Pero, está imprimiendo valor de basura. He revisado el depurador. El puntero devuelto por la llamada "operador char *" no es válido. ¿Alguna idea?"operador char *" problema

class Wrapper 
{ 
private: 
    char* _data; 

public: 

    Wrapper(const char* input) 
    { 
     int length = strlen(input) + 1; 
     _data = new char[length]; 
     strcpy_s(_data, length, input); 
    } 

    ~Wrapper() 
    { 
     delete[] _data; 
    } 

    operator char*() 
    { 
     return _data; 
    } 
}; 

int main() 
{ 
    char* username = Wrapper("kevin"); 
    printf(username); 
    return 0; 
} 
+6

Mi primera sugerencia sería usar std :: string ya que obviamente está usando C++. –

+0

¿por qué editó la etiqueta de punteros que agregué? – James

+0

Tenga en cuenta que generalmente debe evitar las conversiones implícitas. (Y, por supuesto, use 'std :: vector', o' std :: string', etc.) – GManNickG

Respuesta

15

El problema es que su objeto Wrapper se está construyendo como temporal e inmediatamente destruido. A través del operator char* está devolviendo un puntero a la memoria que ha sido eliminado por el objeto Wrapper cuando se destruyó.

Para hacer que funcione:

Wrapper wrapper("Kevin"); 
char* username = wrapper; 
+1

Gracias. Eso es increíblemente rápido. –

+2

@ sankaran1984 Hazle un favor y acepta la respuesta, es la gran marca de verificación a la izquierda. = P – James

+1

Podría ser bueno para los contestadores para votar una pregunta bien expresada de un novato SO también. –

4

Esta línea:

char* username = Wrapper("kevin"); 

crea un objeto de la envoltura sin nombre que se destruye inmediatamente, dejando su puntero que apunta a la nada. Necesita darle un nombre al objeto envoltorio o no escribir un código como ese. Esto funcionaría:

Wrapper w("kevin"); 
char* username = w; 
printf("%s", username); 
4

El puntero está devolviendo está siendo eliminado por el destructor Envoltura tan pronto como se sale del ámbito al final de la primera declaración - antes de que el printf.
En algunos casos, este error puede ocultarse porque la memoria no se puede reclamar inmediatamente y el valor "se ve" bien aunque ya no sea válido. Algunas herramientas pueden ayudar a detectar esto.

1

Esta sentencia crea un objeto temporal Wrapper:

char* username = Wrapper("kevin"); 

Al final de la declaración, ("expresión completa") el objeto Wrapper se destruye. Te queda un puntero colgante (es decir, lo que apunta ha sido eliminado).

Devolver un puntero (o referencia) a los datos internos de un objeto generalmente es peligroso y debe evitarse cuando sea razonable. En cualquier caso, ¿no crees que hay suficientes clases de cuerdas en el mundo? ¿De verdad necesitas escribir otro?