2012-01-15 71 views
8

我正在寻找关于这个话题,我发现很多方法[]数组转换为标准::向量,就像使用:复制数组到一个std ::向量

assign(a, a + n) 

,或者直接在构造函数:

std::vector<unsigned char> v (a, a + n); 

这些解决我的问题,但我想知道是否有可能(正确)的事情:

myvet.resize(10); 
memcpy(&myvet[0], buffer, 10); 

我想知道这是因为我有以下代码:

IDiskAccess::ERetRead nsDisks::DiskAccess::Read(std::vector<uint8_t>& bufferRead, int32_t totalToRead) 
{ 
    uint8_t* data = new uint8_t[totalToRead]; 
    DWORD totalRead; 
    ReadFile(mhFile, data, totalToRead, &totalRead, NULL); 
    bufferRead.resize(totalRead); 
    bufferRead.assign(data, data + totalRead); 
    delete[] data; 

    return IDiskAccess::READ_OK; 
} 

而且我想这样做:

IDiskAccess::ERetRead nsDisks::DiskAccess::Read(std::vector<uint8_t>& bufferRead, int32_t totalToRead) 
{ 
    bufferRead.resize(totalToRead); 
    DWORD totalRead; 
    ReadFile(mhFile, &bufferRead[0], totalToRead, &totalRead, NULL); 
    bufferRead.resize(totalRead); 

    return IDiskAccess::READ_OK; 
} 

(我已删除ReadFile函数的错误处理,简化后)。

它正在工作,但我担心它不安全。我相信这是可以的,因为矢量所使用的内存是连续的,但我从来没有见过有人使用这种方法。

使用这样的向量是否正确?还有其他更好的选择吗?

回答

8

是的,它是安全的,std::vector C++标准保证元素将存储在连续的内存位置。

C++ 11标准:

23.3.6.1类templatevector概述[vector.overview]

的载体是支持随机访问迭代器的序列容器。此外,它还支持(分期付款)恒定时间插入和擦除操作;在线性时间插入和擦除中间。存储管理是自动处理的,尽管提示可以提高效率。 一个向量的元素相邻地存储,这意味着IFV是avector whereT是某种类型的比布尔其它,那么它遵循身份& v [n]的== & v [0] + n,用于ALL0 < = N < v 。尺寸()​​。

1

做你的调整第一,它应该工作正常。

vector<int> v; 
v.resize(100); 
memcpy(&v[0], someArrayOfSize100, 100 * sizeof(int)); 
+3

他*不*调整第一字节不Ë大小(看他的函数的第一行)。 – celtschk 2012-01-15 17:18:18

+1

我并不是暗示他没有这么做。我只是强调它的重要性。 – TheBuzzSaw 2012-01-15 18:08:17

+1

你可能没有*表示*来暗示它,但你做到了。 – celtschk 2012-01-15 18:11:22

2

vector的内存保证连续地分配和unsigned char是POD,因此这是完全安全的,memcpy进去(比假设您已经分配当然,你不要复制更多)。

1

是,使用memcpy溶液是正确的;由vector持有的缓冲区是连续的。但它不是类型安全的,所以更喜欢assignstd::copy

5

是的,这样做很好。如果你看起来更好,你可能想要做myvet.data()而不是&myvet[0],但它们都有相同的效果。另外,如果情况允许,你可以使用std::copy来代替,并且有更多的类型安全和所有其他C++标准库的好处。

一个vector使用存储保证是连续的,这使得它适合于用作缓冲剂或与其他功能。

请确保您不要修改vector(如调用push_back就可以了,等等),而你正在使用你data&v[0]得到的指针,因为vector可以调整所执行的操作的一个它的缓冲区和无效指针。

3

这种方法是正确的,它仅依赖于具有由标准所要求的连续存储器的矢量。我相信在C++ 11中向量中有一个新的data()成员函数,它返回指向缓冲区的指针。还要注意的是在'的情况下的memcpy你需要传递大小的数组

相关问题