2

のサイズがわかっていれば、data19行目で作成できます。vvp.at(0)vf

#include <iostream>
#include <vector>

typedef void* VoidPointer;
typedef std::vector< float > VF;
typedef std::vector< VoidPointer > VVP;

int main(int argc, char** argv)
{
    VF vf;
    vf.push_back(13.0f);
    vf.push_back(14.0f);
    vf.push_back(15.0f);
    vf.push_back(16.0f);

    VVP vvp;
    vvp.push_back( (VoidPointer)const_cast<float *>( &(vf.front()) ) );

    VF data ( static_cast< float* >( vvp.at(0) ),
              static_cast< float* >( vvp.at(0) ) + vf.size() );

    std::cout << "data.size() is " << data.size() << std::endl;

    for(VF::const_iterator i = data.begin(); i != data.end(); ++i)
    {
        std::cout << "data contains " << *i << std::endl;
    }

    return 0;
}

これが賢明かどうかはさておき(例は考案されています)、のサイズがわからない場合は、にキャストvvp.at(0)する方法を知りたいです。私は次のようなものの線に沿って考えています:std::vector<float>vf

std::vector<float> data( *static_cast< std::vector<float>* >( vvp.at(0) ) );

しかし、それによりプログラムはstd :: bad_allocで終了します。必要に応じて、コピーしてもかまいません。

4

2 に答える 2

3

これは、ベクトルへのキャストではなく、 floatの配列を新しいベクトルにコピーしたものです。そして、長さを知らずにそれをコピーすることはできません。最初の要素へのポインタのみを保存したため、情報が失われました。vvp.at(0)

(または、必要に応じて開始ポインタと終了ポインタ)のstd::vector<std::pair<VoidPointer, size_t> > VVP両方を作成して保存できます。&vf.front() vf.size()

std::vector<VF *>ベクトル(つまり)へのポインタを作成して保存することができvvp.push_back(&vf)、今ではキャストはまったくありません。

編集:気づかなかった場合:ポインタ&vfはとは無関係&vf.front()です。 ポインタ(またはポインタを取得する方法)vfを含む構造体です。あなたが見つけられるようにするため&vf.front()のアドレスだけに情報はありません。&vf.front()&vf

于 2012-11-14T01:42:01.447 に答える
1

私が考えることができる唯一のことは、非常にポータブルではない(そして同様にクレイジーである)ことです。各ベクトルは、メモリの連続した配列を割り当てます。割り当て関数は、割り当てられたバイト数を追跡​​する必要があります。これにより、割り当てのアドレスの先頭のみを指定して、割り当てを解除できます。

AFAIK、C ​​++標準は、この簿記がどのように行われるかを指定していないため、これは各コンパイラー次第です。1つの方法は、実際の割り当てアドレスの前にカウントを書き込むことです。これは、VisualC++コンパイラが行うことだと思います。(たとえば、0x104で割り当てる場合、32ビットカウントを0x100に格納できます)。繰り返しになりますが、特定のコンパイラがこの簿記をどのように行うかを知る必要があります。

とにかく、ポイントは、一度実行すると、少しのポインタ演算と逆参照によって、理論的に割り当てられたサイズを検索でき(もちろん、ここではデフォルトのアロケータを備えたベクトルを使用していると仮定しています)、その方法を理解することができます多くのフロートは、実際にはvoidポインタのみを使用して割り当てられました。

次に、32ビットデバッグモードのVisualStudioで機能する例を示します。

#include <iostream>
#include <vector>

size_t bytes_allocated( void* p )
{
#ifndef _DEBUG
#error Doesn't work
#endif // _DEBUG
    size_t const offset = 12;
    size_t const counter_size = 4;
    size_t const total_offset = offset + counter_size;
    void* counter_address = ((char*)p)-total_offset;
    size_t* count = reinterpret_cast<size_t*>(counter_address);
    return *count;
}

int main(int argc, char* argv[])
{
    typedef float test_type;
    std::vector<test_type> v;
    v.push_back(23);
    v.push_back(23);
    v.push_back(23);
    size_t count = bytes_allocated(&v[0]);
    std::cout<<count<<" bytes allocated\n";
    std::cout<<count/sizeof(test_type)<<" items allocated\n";
    return 0;
}

出力は次のとおりです。

12 bytes allocated
3 items allocated
于 2012-11-14T01:53:13.567 に答える