简体   繁体   English

如何将void *返回std :: vector <float>

[英]How to cast void* back to std::vector<float>

I can construct data on Line 19 from vvp.at(0) if I know the size of vf . 如果知道vf的大小,我可以从vvp.at(0)在19行构造data

#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;
}

Leaving aside whether this is sensible (the example is contrived) I'd like to know how to cast vvp.at(0) to a std::vector<float> if I didn't know the size of vf . 抛开这是否明智(该示例是人为设计的),如果我不知道vf的大小,我想知道如何将vvp.at(0)转换为std::vector<float> I'm thinking along the lines of something like: 我在想类似的东西:

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

But that causes the program to termintate with std::bad_alloc, I don't mind copying if need be. 但这导致程序以std :: bad_alloc终止,如果需要的话,我不介意进行复制。

That is not a cast from vvp.at(0) to a vector, it's a copy of an array of floats into a new vector. 这不是从 vvp.at(0)到一个向量,它是漂浮的阵列的拷贝到一个新的载体。 And you can't copy it without knowing the length. 而且您无法在不知道长度的情况下进行复制。 You only saved a pointer to the first element, so the information was lost. 您仅保存了指向第一个元素的指针,因此信息丢失了。

You could make std::vector<std::pair<VoidPointer, size_t> > VVP and save both &vf.front() and vf.size() (or start and end pointers, if you prefer). 您可以使std::vector<std::pair<VoidPointer, size_t> > VVP并保存&vf.front() vf.size() (或者,如果愿意,可以使用开始和结束指针)。

You could make std::vector<VF *> and store pointers to vectors (ie vvp.push_back(&vf) ) and now there's no casting at all. 您可以制作std::vector<VF *>并存储指向矢量的指针(即vvp.push_back(&vf) ),现在完全没有强制转换。

Edit: In case you didn't realize: The pointer &vf is unrelated to &vf.front() . 编辑:如果您没有意识到:指针&vf&vf.front()无关。 vf is a structure which contains the pointer &vf.front() (or a way to get it). vf是一个包含指针&vf.front() (或获取它的方法)。 There's no information in just the address &vf.front() to let you find &vf . 仅在地址&vf.front()没有任何信息可让您找到&vf

The only thing I can think of is extremely non-portable (and equally crazy). 我唯一能想到的就是极其不可携带(同样疯狂)。 Each vector allocates a contiguous array of memory. 每个向量分配一个连续的内存数组。 Any allocation function has to keep track of how many bytes have been allocated, so that it can de-allocate them given only the beginning of the allocation's address. 任何分配函数都必须跟踪已分配了多少个字节,以便仅在分配地址的开头就可以取消分配它们。

AFAIK, the C++ standard does not specify how this book keeping is done and therefore, this up to each compiler. AFAIK,C ++标准没有指定如何完成此簿记,因此,这取决于每个编译器。 One method is to write a count before the actual allocation address - I believe this is what the Visual C++ compiler does. 一种方法是在实际分配地址之前写一个计数-我相信这是Visual C ++编译器所做的。 (Eg. if allocating at 0x104, a 32-bit count could be stored at 0x100). (例如,如果分配为0x104,则32位计数可以存储在0x100)。 Again, you will have to know how your specific compiler does this book keeping. 同样,您将必须知道您的特定编译器如何完成此工作。

Anyway, the point is, once you do, a little pointer arithmetic and de-referencing could theoretically look up the allocated size (I'm of course assuming you're still using a vector with a default allocator here), and figure out how many floats were actually allocated using only a void pointer. 无论如何,关键是,一旦完成,理论上只需进行一点指针算术和解引用就可以查找分配的大小(我当然假设您在此处仍在使用带有默认分配器的向量),并弄清楚如何实际上仅使用void指针分配了许多浮点数。

Here's an example that works in Visual Studio in 32-bit debug mode: 这是在Visual Studio中以32位调试模式工作的示例:

#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;
}

The output is: 输出为:

12 bytes allocated
3 items allocated

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM