2012-02-10 12 views
1

Windowsでは、GlobalAllocnewに置き換えるにはどうすればよいですか? GlobalAllocでメモリを割り当てる :Windowsでは、 `GlobalAlloc`を` new`で置き換えるにはどうしたらいいですか?

こんにちは、 私は("Reading from a Mailslot"ここから)このコードのスニペットを持っています。

DWORD cbRead = 0; 
LPTSTR lpszBuffer = (LPTSTR) ::GlobalAlloc(GPTR, cbMessage); //cbMessage is from a call to GetMailslotInfo 
if(NULL == lpszBuffer) 
    return FALSE; 
lpszBuffer[0] = '\0'; 
BOOL fResult = ::ReadFile(hSlot, lpszBuffer, cbMessage, &cbRead, 0); 
if (fResult) 
{ 
    _tprintf(TEXT("Contents of the mailslot: %s\n"), lpszBuffer); 
} 
::GlobalFree((HGLOBAL) lpszBuffer); 

私は、コードを変更し、代わりにGlobalAllocの代わりに裸LPTSTR(およびGlobalFreeを取り除くために)とnewのスマートポインタを使用したいと思います。 cbMessageは "次のメッセージのサイズ(バイト)"なので、mallocのようなものが必要です。これは型なしメモリで動作します。newは私の場合に適していますか?

+0

このコードは、 'fResult == FALSE'のときにリークします。 – tibur

+0

@tiburはい、私はそれを修正します。ありがとうございました。 –

+1

はい、ただ電話するだけです。 sizeof(TCHAR)を考慮に入れてください。また、なぜあなたはまだ 'TCHAR'を持っていますか?それは長い過去の時間です。 –

答えて

3

通常、できません。

異なるメモリ割り当て関数(GlobalAllocmallocnewSysAllocVirtualAllocHeapAlloc)は、他の違いをそれらが、異なる方法、異なる場所、異なるサイズのメモリを割り当てる異なってタグ付けするので、存在する異なる下地マネージャを使用し、無数。それらのうちのいくつかはローカルヒープにあり、一部はグローバルであり、いくつかは仮想であり、一部は指定しないものもあれば、メモリを割り当てたり、SysAllocStringやCoGetMallocのようなCOMで動作する他のものもあります。

コールが1つのアロケータを使用するように指定した場合、そのメモリを別のプロセスまたはそのアロケータを必要とするその他の動作に渡す可能性のある基になるコードがあります。別のものを使用しようとすることはできますが、未定義の動作になる可能性があります。

他のアロケータでスマートポインタを使用するには、できることがいくつかあります。最も簡単なのは、スマートポインタクラスにallocatorとdeallocatorの関数としてそれらを提供し、それが適切に処理できるようにすることです。選択したポインタに応じて、これにはいくつか微調整が必​​要な場合や、そのアロケータで作業できる基本的なスマートポインタをまとめなければならない場合があります。

MFCおよび/またはATLには、1つまたは複数の特殊なアロケータで動作するスマートポインタとヘルパ関数が用意されていることがよくあります。それらを使用することが可能な場合は、それを調べることができます。

+3

しかし、与えられたコードでは、それは起こりません。 –

1
boost::scoped_array<TCHAR> buffer(new TCHAR[cbMessage/sizeof(TCHAR)]); 
buffer[0] = 0; 
BOOL fResult = ::ReadFile(hSlot, buffer.get(), cbMessage, &cbRead, 0); 
if (fResult) 
{ 
    _tprintf(TEXT("Contents of the mailslot: %s\n"), buffer.get()); 
} 

スマートポインタを使用してメモリを管理するため、明示的にメモリを解放する必要はありません。 (ブーストscoped_array

+0

@alf std :: stringのメモリに移植可能に直接書き込むことはできません。私はTのものはナンセンスだと同意するが、それは質問に関連していないようだ。スマートポインタへの移行に関心のある人にとって、ブーストは非常に便利になるだろう。 –

+1

申し訳ありませんが、あなたはstd :: stringについて間違っています。また、申し訳ありませんが、Boostは私がここで想像できるもののために必要ではありません。標準ライブラリには十分なスマートポインタがあります。 –

+1

@ AlfP.Steinbach、良い点が、私はそれが-1を正当化するとは思わない。これがMBCSに残っているレガシーコードではないことを示すことは何の質問にもありません。スマートポインタには他にも選択肢がありますが、この選択肢は間違っていません。このような状況のために設計されました。 –

関連する問題