2016-04-23 3 views
-1

Ich habe eine Funktion, die eine Million Mal in meinem Code verwendet wird, und es ist ein Speicherleck drin.So vermeiden Sie Memory Leak mit der Rückgabe von const char *

Es dauert eine const wchar_t* als Eingabe und gibt eine const char* zurück. Jetzt verstehe ich, dass dieser Zeiger zurückgegeben() wäre erforderlich, um eine explizite delete[] von der aufrufenden Funktion (aber ich kann es mir nicht leisten), da dies würde bedeuten, ich muss es an allen Standorten ändern.

Der Code ist wie:

inline const char * W2N(const wchar_t* wstr) 
{ 
    int cw=lstrlenW(wstr); 

    if (cw==0) 
    { 
     CHAR *psz=new CHAR[1]; *psz='\0'; return psz; 
    } 

    int cc=WideCharToMultiByte(CP_ACP,0,wstr,cw,NULL,0,NULL,NULL); 
    if (cc==0) return NULL; 

    CHAR *psz=new CHAR[cc+1]; 
    cc=WideCharToMultiByte(CP_ACP,0,wstr,cw,psz,cc,NULL,NULL); 
    if (cc==0) 
    { 
     delete[] psz; return NULL; 
    } 

    psz[cc]='\0'; 
    return psz; 
} 

Gibt es etwas, dass ich um diese Funktion tun können Speicherverlust zu vermeiden.

+0

Vereinbart tobi303, aber der Zeiger psz, der am Ende zurückgegeben wird, verursacht Leck, da es nie freigegeben wurde. –

+0

Wissen Sie, wann die Clientaufruffunktion den von 'W2N()' zurückgegebenen Speicher beendet hat? – quamrana

+3

Warum nicht 'std :: string' anstelle von' char * 'verwenden? – Barmar

Antwort

2

Sie können und sollten Ihren Zeiger in eine std::unique_ptr<char[]> einbinden. Dies wird Ihr genaues Problem auf eine idiomatische C++ - Art lösen.

Dies wird Ihre Funktion wie folgt ändern:

inline std::unique_ptr<char[]> W2N(const wchar_t *wstr) { 
    int cw = lstrlenW(wstr); 

    if(cw == 0) { 
     auto psz = std::make_unique<char[]>(1); 
     psz[0] = '\0'; 
     return psz; 
    } 
    int cc = WideCharToMultiByte(CP_ACP, 0, wstr, cw, NULL, 0, NULL, NULL); 
    if(cc == 0) 
     return nullptr; 
    auto psz = std::make_unique<char[]>(cc + 1); 
    cc = WideCharToMultiByte(CP_ACP, 0, wstr, cw, psz, cc, NULL, NULL); 
    if(cc == 0) { 
     return nullptr; 
    } 
    psz[cc] = '\0'; 
    return psz; 
} 

Dies setzt natürlich voraus, dass Sie Zugriff auf einen C++ 14-konformen Compiler (für std::make_unique) oder zumindest C++ 11 konform (für std::unique_ptr).

Natürlich, wie in den Kommentaren angegeben, können Sie eine std::string zurückgeben. Wenn Sie dies tun, achten Sie darauf, dass die Rückgabe der Funktion nullptr oder NULL wahrscheinlich fehlerhaft ist.