2009-08-01 21 views
10

Soy un novato en C++. Estoy tratando de tener un puntero char como un parámetro de salida para una función. Pero los cambios realizados en la función no se reflejan en la función principal. ¿Qué estoy haciendo mal?Cómo tener un puntero char como un parámetro de salida para la función C++

void SetName(char *pszStr) 
{ 
    char* pTemp = new char[10]; 
    strcpy(pTemp,"Mark"); 
    pszStr = pTemp; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char* pszName = NULL; 
    SetName(pszName); 
    cout<<"Name - "<<*pszName<<endl; 
    delete pszName; 
    return 0; 
} 

Respuesta

48

Su puntero se está copiando en la pila, y está asignando el puntero de la pila. Tiene que pasar un puntero a puntero si desea cambiar el puntero:

void SetName(char **pszStr) 
{ 
    char* pTemp = new char[10]; 
    strcpy(pTemp,"Mark"); 
    *pszStr = pTemp; // assign the address of the pointer to this char pointer 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char* pszName = NULL; 
    SetName(&pszName); // pass the address of this pointer so it can change 
    cout<<"Name - "<<*pszName<<endl; 
    delete pszName; 
    return 0; 
} 

que va a resolver su problema.


Sin embargo, hay otros problemas aquí. En primer lugar, está desreferenciando su puntero antes de imprimir. Esto es incorrecto, el puntero es un puntero a un array de caracteres, por lo que desea imprimir toda la matriz:

cout<<"Name - "<<pszName<<endl; 

Lo que tenemos ahora se acaba de imprimir el primer carácter. Also, es necesario utilizar delete [] eliminar una matriz: problemas

delete [] pszName; 

más grandes, sin embargo, están en su diseño.

Ese código es C, no C++, e incluso entonces no es estándar. En primer lugar, la función que estás buscando es main:

int main(int argc, char * argv[]) 

En segundo lugar, se debe utilizar references en lugar de punteros:

void SetName(char *& pszStr) 
{ 
    char* pTemp = new char[10]; 
    strcpy(pTemp,"Mark"); 
    pszStr = pTemp; // this works because pxzStr *is* the pointer in main 
} 

int main(int argc, char * argv[]) 
{ 
    char* pszName = NULL; 
    SetName(pszName); // pass the pointer into the function, using a reference 
    cout<<"Name - "<<pszName<<endl; 
    delete pszName; 
    return 0; 
} 

Aparte de eso, por lo general es mejor simplemente volver las cosas si se puede :

char *SetName(void) 
{ 
    char* pTemp = new char[10]; 
    strcpy(pTemp,"Mark"); 
    return pTemp; 
} 

int main(int argc, char * argv[]) 
{ 
    char* pszName = NULL; 
    pszName = SetName(); // assign the pointer 
    cout<<"Name - "<<pszName<<endl; 
    delete pszName; 
    return 0; 
} 

Hay algo que hace todo esto mejor. C++ tiene una string class:

std::string SetName(void) 
{ 
    return "Mark"; 
} 

int main(int argc, char * argv[]) 
{ 
    std::string name; 

    name = SetName(); // assign the pointer 

    cout<<"Name - "<< name<<endl; 

    // no need to manually delete 
    return 0; 
} 

Si por supuesto todo esto puede ser simplificado, si quieres:

#include <iostream> 
#include <string> 

std::string get_name(void) 
{ 
    return "Mark"; 
} 

int main(void) 
{ 
    std::cout << "Name - " << get_name() << std::endl;   
} 

usted debe trabajar en su formato para hacer las cosas más fácil de leer. Espacios entre medio de sus operadores de ayuda:

cout<<"Name - "<<pszName<<endl; 

cout << "Name - " << pszName << endl; 

Al igual que en los espacios entre las palabras inglesas ayuda, sodoesspacesbetweenyouroperators. :)

+2

+1, responde el problema directo e ilumina el problema mayor con el código. –

+0

Gracias GMan. Fue realmente informativo. – Mark

+0

No hay problema :) – GManNickG

2

Lo que está escribiendo no es C++, sino un código C que usa nuevo en lugar de malloc y lo elimina en lugar de hacerlo gratis. Si realmente quieres escribir el código C++, comienza de nuevo. Lea un libro como Accelerated C++, que le enseñará C++ idiomático moderno.

+0

Esto no responde exactamente la pregunta, pero es una buena sugerencia ... – Zifre

+2

La última línea de la pregunta fue "¿Qué estoy haciendo mal?" Creo que mi respuesta aborda esto exactamente. –

+0

Gracias por la sugerencia. Definitivamente voy a repasar el libro. – Mark

4

Dado que etiquetó como C++, ¿por qué no pasar una referencia std :: string y completarlo?

void GetName(std::string &strName) 
{ 
    strName = "Mark"; 
} 

O simplemente devolver un std :: string:

std::string GetName2() 
{ 
    return "Mark"; 
} 

y llamarlo como tal

std::string strName, strName2; 
GetName(strName); 
strName2 = GetName2(); 
assert(strName == "Mark"); 
assert(strName2 == "Mark"); 
//strName.c_str() returns the const char * pointer. 

Entonces usted no tiene que preocuparse de liberar cualquier memoria.

+0

Y no se olvide de #include :) –

7

También puede utilizar una referencia a un puntero en este caso. Además, es posible que desee conocer otros 2 errores que están en el código original (vea mis comentarios en el fragmento de código).

void SetName(char *& pszStr) 
{ 
    char* pTemp = new char[10]; 
    strcpy(pTemp,"Mark"); 
    pszStr = pTemp; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char* pszName = NULL; 
    SetName(pszName); 

    // Don't need '*' in front of pszName. 
    cout<< "Name - " << pszName << endl; 

    // Needs '[]' to delete an array. 
    delete[] pszName; 
    return 0; 
} 
+0

Buena captura en la matriz de eliminar. – GManNickG

Cuestiones relacionadas