1

バックグラウンド

テストのために Intel IPP Cryptographic Libraries を使用しています。

それらは、もちろん直接インスタンス化できないハッシュや暗号化などの共有コンテキストに使用されるいくつかの不透明な構造体を定義します。

これらの不透明な構造体の 1 つを初期化するには、バイト サイズをクエリしてから、いくつかのバイトを動的に割り当て、構造体ポインターにキャストします。

彼らの例は次のように機能します。

int byteSize = 0;
ippsSHA256GetSize(&byteSize);

// IppsSHA256State shaCtx; // Error: incomplete type is not allowed
IppsSHA256State * shaCtx = (IppsSHA256State *)(new uint8_t[byteSize]);
// use shaCtx
delete [] (uint8_t *)shaCtx;

質問

割り当て解除について心配する必要がないように、スコープ付きポインター クラスでこれをラップする適切な方法は何ですか?


私が試したこと

デストラクタでのdeleteの呼び出しは、実際に割り当てられた配列のdelete []ではなく T 型になるため、次のことは安全ではないと思います。

boost::scoped_ptr<IppsSHA256State> ctx(
    reinterpret_cast<IppsSHA256State *>(new uint8_t[byteSize])
    );

私が検討した別の (簡略化された) オプションは、私自身の単純なスコープ ポインター クラスですが、そこでキャストすると、これが正しいかどうかわかりません。あいまいさがあります:

template <typename T>
class IppsScopedState
{
public:
    explicit IppsScopedState(size_t byteSize)
        : _ptr(reinterpret_cast<T *>(new uint8_t[byteSize]))
    {}

    T * get() const { return _ptr; }

    ~IppsScopedState(void) {
        if (_ptr) delete [] reinterpret_cast<uint8_t *>(_ptr);
    }
private:
    T * _ptr;
    //NUKE_COPYASSIGN_CONSTRUCTORS
};

最後に、上記のわずかなバリエーションを検討しました。

template <typename T>
class IppsScopedState
{
public:
    explicit IppsScopedState(size_t byteSize)
        : _ptr(new uint8_t[byteSize])
    {}

    T * get() const { return reinterpret_cast<T *>(_ptr); }

    ~IppsScopedState(void) {
        if (_ptr) delete [] _ptr;
    }
private:
    uint8_t * _ptr;
    //NUKE_COPYASSIGN_CONSTRUCTORS
};

どちらの場合でも、使用法は次のようになります。

IppsScopedState<IppsSHA256State> ctx(byteSize); // after querying for the byteSize, of course
4

2 に答える 2

0

あなたはこれが正しいです:

boost::scoped_ptr<IppsSHA256State> ctx(
    reinterpret_cast<IppsSHA256State *>(new uint8_t[byteSize])
);

deleteの代わりに が呼び出されることとdelete[]、間違った型を削除することの 2 つの理由から、これは悪い考え です。

boost::scoped_arrayうまくいくはずです:

boost::scoped_array<uint8_t> temparray (new uint8_t[byteSize]);
IppsSHA256State * shaCtx = (IppsSHA256State *)(temparray.get());

しかし、これにより 2 つのローカル変数が得られshaCtxますtemparray。そのため、独自のラッパーをロールすることは非常に魅力的なオプションです。安全性が得られるからです。

あなたの現在は問題ありませんが、boost::scoped_array を内部で使用し、アクセサーを追加し、アクセスを constIppsScopedStateするために、少し調整することをお勧めします。operator->

template <typename T>
class IppsScopedState
{
public:
    explicit IppsScopedState(size_t byteSize)
        : _ptr(new uint8_t[byteSize])
    {}

    const T* operator->() const { return get(); }
    T* operator->() { return get(); }
    const T* get() const  { return reinterpret_cast<const T*> (_ptr.get()); }
    T* get()   { return reinterpret_cast<T*>(_ptr.get()); }

private:
    boost::scoped_array<uint8_t> _ptr;
    //NUKE_COPYASSIGN_CONSTRUCTORS
};

次に、このラッパーを簡単に使用できます。

IppsScopedState<IppsSHA256State> shaCtx (byteSize);
shaCtx->member;  // access any member of IppsSHA256State
some_function(shaCtx.get());  // pass the IppsSHA256State* to a method

必要に応じて、operator->and constget()はやり過ぎで不要な場合があります。

したがって、最後に、カスタム ラッパーをお勧めし、古い C スタイルのキャスト構文よりも reinterpret_cast を使用することをお勧めします。

于 2011-08-09T00:25:08.407 に答える
0

boost::scoped_arrayまたは だけを使用できますstd::vector

于 2011-08-09T00:04:34.060 に答える