0

C ++でのメモリ管理に関しては、私はちょっと新しいです。newキーワードを使用してクラスを作成する場合delete、オブジェクトのメモリを解放する必要があることを読みました。intまた、char、、 などのプリミティブ型boolがスタック上に作成されることも読みました。これは、スコープ外に出ると削除されることを意味します。

newしかし、キーワードで作成されたプリミティブ型はどうなるでしょうか? 明示的に呼び出す必要がありますdeleteか? これらはヒープのようなクラスで作成されますか? それとも、それらはプリミティブであるため、スタック上に作成されますか?

newキーワードを使ってaを確保しているので質問しているのですが、それを呼ばないとメモリが解放されないのでLPTSTRはないかと心配です。deleteコメントに裸の質問がある私のコードは次のとおりです。

#include <Windows.h>
#include <tchar.h>
#include <string>

#ifdef _UNICODE
    typedef std::wstring Str;
#else // ANSI
    typedef std::string Str;
#endif

Str GetWndStr(HWND hwnd) {
    const int length = GetWindowTextLength(hwnd);

    if (length != 0) {
        LPTSTR buffer = new TCHAR[length + 1]; // Allocation of string
        GetWindowText(hwnd, buffer, length + 1);
        Str text(buffer);

        delete buffer; // <--- Is this line necessary?
        return text;
    } else {
        return _T("");
    }
}

電話する必要がありますdeleteか?GlobalAlloc()しばらく前にandを使用してみGlobalFree()ましたが、実行時にスタックの不正な変更に関するエラーが表示されました。これは少し前のことなので、正確なエラー メッセージはありません。また、あなたの回答に加えて、C++ メモリ管理の詳細を学ぶのに役立つリソースを提供していただければ幸いです。

4

5 に答える 5

8

ごとnewに が存在する必要がありdelete、すべてnew[]に が存在する必要がありますdelete[]。で割り当てられたメモリnew[]は で削除する必要があることに注意してくださいdelete[]。これは、投稿されたコードには当てはまりません。

boost::scoped_arrayたとえば、delete[]デストラクタ (またはreset()関数)で実行するスマート ポインタを使用できます。これは、 への呼び出し後に例外をスローできる場合に特に便利ですnew[]

boost::scoped_array<TCHAR> buffer(new TCHAR[length + 1]);
GetWindowText(hwnd, buffer.get(), length + 1);
Str text(buffer.get()); // buffer will be deleted at end of scope.
于 2012-10-26T10:28:58.237 に答える
7

配列はで割り当てられるため、 (ではなくnew[])で削除する必要があります。delete[] delete

明示的な動的割り当ても不要です。

Str text(length+1, 0);
GetWindowText(hwnd, &text[0], length + 1);
text.resize(length); // remove NUL terminator
return text;

C ++ 03では、バッファとして渡すのに適した、連続したメモリを割り当てるかどうかstring、実際に割り当てるかどうかなど、いくつかの正当化が必要です。wstringC ++ 03標準では保証されていませんが、実際にはMSVC++では当てはまります。その事実に依存したくない場合は、それベクトルに対して保証されているので、それをバッファーに使用できます。

std::vector<TCHAR> buffer(length+1);
GetWindowText(hwnd, &buffer[0], length + 1);
return Str(buffer.begin(), buffer.end() - 1);

new[]C++で直接使用することは非常にまれです。どちらの場合も、myvectorまたはstringbufferは自動変数であるため、スコープが終了したときに正しく破棄されるようにするために特別なことをする必要はありません。

于 2012-10-26T10:42:49.173 に答える
2

はい (スマート ポインターなどを使用して削除しない限り)

于 2012-10-26T10:28:00.937 に答える
2

はい、ルールはとても簡単です。割り当てたものはすべて、割り当てをnew解除する必要がありますdelete。で割り当てられたものはすべて、 で割り当てをnew[]解除する必要がありますdelete[]

エラーの可能性を減らすには、コンテナー、スマート ポインター、またはその他のRAIIスタイル オブジェクトを使用して動的リソースを管理することをお勧めしdeleteます。

于 2012-10-26T10:28:21.263 に答える
0

もちろん、割り当てられたタイプに関係なく。まだメモリスペースがあります。

于 2012-10-26T10:28:10.283 に答える