2

次のコード:

class Something
{
public:
     ~Something()
    {
    }
};

int main()
{
    Something* s = new Something[1]; // raw pointer received from C api
    std::shared_ptr<Something> p = std::shared_ptr<Something>(s);
    std::vector<std::shared_ptr<Something>> v(&p,&p+1);

    return 0;
}

VS Express 2010 で次のエラーが発生します。

---------------------------
Microsoft Visual C++ Debug Library
---------------------------
Debug Assertion Failed!

File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
Line: 52

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

何かからデストラクタを削除すると、エラーが消えます。なぜこのエラーが発生するのですか?

アップデート:

後で私は次のようなものになります:

Something* s = new Something[100];

個々の共有ポインタは他のオブジェクトに渡されます

4

2 に答える 2

6
Something* s = new Something[1]; // raw pointer received from C api
std::shared_ptr<Something> p = std::shared_ptr<Something>(s); 

は間違った使い方です。

~shared_ptr();

効果: — *this が空であるか、別の shared_ptr インスタンスと所有権を共有している場合 (use_count() > 1)、副作用はありません。

— それ以外の場合、*this がオブジェクト p とデリータ d を所有している場合、d(p) が呼び出されます。

— それ以外の場合、*this はポインター p を所有し、delete p が呼び出されます。

デフォルトのデリータはoperator deleteですが、Something* s = new Something[1];array-new 演算子によって割り当てられているため、array-delete 演算子 (delete[]) で削除する必要があります。そうしないと、未定義の動作になります。特定のデリータを使用して shared_ptr を構築するか、配列に何かを使用する必要がありますboost::shared_array

たとえば、このコードは正しいです。

template<typename T>
void deleter(T* p)
{
   delete[] p;
}

Something* s = new Something[1]; // raw pointer received from C api
std::shared_ptr<Something> p = std::shared_ptr<Something>(s, deleter<Something>);
于 2012-08-16T11:05:40.090 に答える
1

動的に割り当てられたポインターでいっぱいのC配列があるとすると、shared_ptrのベクトルの使用は大幅に簡略化されます。

#include <vector>
#include <memory>

struct Foo { };

int main() {

  Foo* foos[5]; // simulate the array of pointers from C API
  foos[0] = new Foo();
  foos[1] = new Foo();
  foos[2] = new Foo();
  foos[3] = new Foo();
  foos[4] = new Foo();

  // create vector of shared_ptrs to C pointers
  std::vector<std::shared_ptr<Foo>> v(foos, foos+5);

}
于 2012-08-16T11:33:10.470 に答える