1. ホーム
  2. c++

[解決済み] 割り当て済み配列を保持する unique_ptr の適切な作成方法

2023-03-23 21:54:21

質問

フリーストアに割り当てられた配列を保持する unique_ptr を作成する適切な方法は何でしょうか。Visual Studio 2013はデフォルトでこれをサポートしていますが、Ubuntuでgccバージョン4.8.1を使用すると、メモリリークと未定義の動作が発生します。

この問題は、このコードで再現できます。

#include <memory>
#include <string.h>

using namespace std;

int main()
{
    unique_ptr<unsigned char> testData(new unsigned char[16000]());

    memset(testData.get(),0x12,0);

    return 0;
}

Valgrindはこのような出力をします。

==3894== 1 errors in context 1 of 1:
==3894== Mismatched free() / delete / delete []
==3894==    at 0x4C2BADC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3894==    by 0x400AEF: std::default_delete<unsigned char>::operator()(unsigned char*) const (unique_ptr.h:67)
==3894==    by 0x4009D0: std::unique_ptr<unsigned char, std::default_delete<unsigned char> >::~unique_ptr() (unique_ptr.h:184)
==3894==    by 0x4007A9: main (test.cpp:19)
==3894==  Address 0x5a1a040 is 0 bytes inside a block of size 16,000 alloc'd
==3894==    at 0x4C2AFE7: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3894==    by 0x40075F: main (test.cpp:15)

どのように解決するのですか?

を使用して T[] の特殊化を使用します。

std::unique_ptr<unsigned char[]> testData(new unsigned char[16000]());

理想的な世界では、明示的に new をインスタンス化するために unique_ptr をインスタンス化することで、潜在的な例外安全性の落とし穴を回避することができます。この目的のために、C++14 では std::make_unique 関数テンプレートが用意されています。参照 この優れたGOTW を参照してください。構文は

auto testData = std::make_unique<unsigned char[]>(16000);