2009-08-01 6 views
10

Sono un novizio di C++. Sto cercando di avere un puntatore char come parametro out per una funzione. Ma le modifiche apportate nella funzione non si riflettono nella funzione principale. Che cosa sto facendo di sbagliato?Come avere un puntatore char come parametro out per la funzione 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; 
} 

risposta

48

Il puntatore viene copiato nello stack e si assegna il puntatore dello stack. È necessario passare un puntatore a puntatore se si desidera modificare il puntatore:

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; 
} 

Ciò risolverà il problema.


Tuttavia, ci sono altri problemi qui. In primo luogo, stai dereferendo il puntatore prima di stampare. Questo non è corretto, il puntatore è un puntatore a un array di caratteri, in modo che si desidera stampare l'intero array:

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

quello che hai ora sarà solo stampare il primo carattere. Also, è necessario utilizzare delete [] per eliminare un array: problemi

delete [] pszName; 

più grandi, però, sono nel vostro disegno.

Quel codice è C, non C++, e anche in questo caso non è standard. In primo luogo, la funzione che stai cercando è main:

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

In secondo luogo, è necessario utilizzare references invece di puntatori:

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; 
} 

A parte questo, di solito è meglio tornare appena le cose, se possibile :

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; 
} 

C'è qualcosa che rende tutto questo migliore. C++ ha un 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; 
} 

Se Naturalmente tutto questo può essere semplificata, se si vuole:

#include <iostream> 
#include <string> 

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

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

si dovrebbe lavorare sulla formattazione per rendere le cose più leggibile. Gli spazi trascorre i vostri operatori aiuta:

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

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

Proprio come spazi tra le parole inglesi aiuta, sodoesspacesbetweenyouroperators. :)

+2

+1, risponde al problema diretto e illumina il problema più grande con il codice. –

+0

Grazie GMan. E 'stato davvero informativo. – Mark

+0

Nessun problema :) – GManNickG

2

Quello che stai scrivendo non è C++, ma il codice C che usa nuovo invece di malloc, ed elimina invece di libero. Se vuoi veramente scrivere codice C++, ricomincia. Leggi un libro come Accelerated C++, che ti insegnerà il moderno C++ idiomatico.

+0

Questo non risponde esattamente alla domanda, ma è un buon suggerimento ... – Zifre

+2

L'ultima riga della domanda era "Cosa sto facendo di sbagliato?" Penso che la mia risposta si riferisca esattamente a questo. –

+0

Grazie per il suggerimento. Farò sicuramente il libro. – Mark

4

Poiché è stato taggato come C++, perché non passare un riferimento a std :: string e riempirlo?

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

O semplicemente restituire uno std :: string:

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

e chiamarlo in questo modo

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

Allora non dovete preoccuparvi di liberare la memoria.

+0

E non dimenticarti di #include :) –

7

In questo caso è anche possibile utilizzare un riferimento a un puntatore. Inoltre, potresti voler essere a conoscenza di altri 2 bug che si trovano nel codice originale (vedi i miei commenti nello snippet di codice).

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

Un bel problema con l'array delete. – GManNickG

Problemi correlati