2016-04-23 21 views
-1

私のコードで何百万回も使用されている関数があり、メモリリークがあります。const charを返すことでメモリーリークを回避する方法*

入力としてconst wchar_t*が入力され、const char*が返されます。 私はこのポインタが返された(const char*)明示的なdelete[]を呼び出す関数から取得する必要があることを理解していますが、これは私がすべての場所でそれを変更する必要があるためです。

コードは次のようである:

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

は、私はメモリリークを避けるために、この機能の周りに何かできることはあります。

+0

tobi303と合意しましたが、最後に返されたポインタpszは決して割り当て解除されなかったため、リークを引き起こしています。 –

+0

クライアント呼び出し関数が 'W2N()'によって返されたメモリで終了したことを知っていますか? – quamrana

+3

'char *'の代わりに 'std :: string'を使わないのはなぜですか? – Barmar

答えて

2

std::unique_ptr<char[]>の中にポインタをラップすることができます。これは、あなたの正確な問題を、慣用的なC++の方法で解決します。

これは、このようなあなたの機能を変更します:

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

これを、もちろん、あなたが(std::make_unique用)C++ 14準拠したコンパイラへのアクセス権を持っていることを前提とし、または準拠した少なくともC++ 11 (std::unique_ptrの場合)。

もちろん、コメントに記載されている通り、std::stringを返すことができます。その場合は、関数からnullptrまたはNULLを返すとおそらくsegfaultになることに注意してください。

関連する問題