简体   繁体   English

std :: vector和c风格的数组

[英]std::vector and c-style arrays

I am experimenting with OpenCL to increase the speed of our software. 我正在尝试使用OpenCL来提高我们软件的速度。 We work with maps a lot and, to simplify, represent a map as a std::vector< std::vector >. 我们经常使用地图,为简化起见,将地图表示为std :: vector <std :: vector>。 The OpenCL API takes raw c-style pointers as arguments, for example int* in the case above. OpenCL API将原始的c样式指针作为参数,例如上面的情况中的int *。

My questions: 我的问题:

  • Are there implementation guarantees in the stl that vector is, internally, consecutive in memory? 在stl中是否存在实现保证,向量内部是否在内存中连续?
  • Can I safely cast a std::vector to int* and expect that to work? 我可以安全地将std :: vector转换为int *并期望它能够工作吗?
  • In the case of a vector of vectors, can I still assume this holds true? 在向量向量的情况下,我仍然可以认为这是正确的吗? I would expect the vector to hold other state data, or alignment issues, or maybe something else... 我希望矢量可以保存其他状态数据,或对齐问题,或者其他东西......
  • What is the best way to approach this? 解决这个问题的最佳方法是什么? Write a custom 2d data structure that holds an internal, contiguous-in-memory buffer and work with that? 编写一个自定义的2d数据结构,它包含一个内部的,连续的内存缓冲区并使用它? I'd have to copy to/from vectors a lot... 我必须要复制到矢量/从矢量...

Thanks. 谢谢。

Are there implementation guarantees in the stl that vector is, internally, consecutive in memory? 在stl中是否存在实现保证,向量内部是否在内存中连续?

As of C++03, yes, a vector is guaranteed to use contiguous storage. 从C ++ 03开始,是的,保证向量使用连续存储。 (In C++98, there was an accidental loophole so an implementation could hypothetically use non-contiguous storage, but it was fixed in the 2003 revision of the standard - and no implementation actually used non-contiguous storage because it'd be a terrible idea) (在C ++ 98中,存在意外漏洞,因此实现可以假设使用非连续存储,但它在2003版本的标准中得到修复 - 并且没有实现实际使用非连续存储,因为它是一个可怕的想法)

Can I safely cast a std::vector to int* and expect that to work? 我可以安全地将std :: vector转换为int *并期望它能够工作吗?

The usual way is &v[0] . 通常的方法是&v[0] ( &*v.begin() would probably work too, but I seem to recall there's some fluffy wording in the standard that makes this not 100% reliable) &*v.begin()可能也会起作用,但我似乎记得标准中有一些蓬松的措辞使得这不是100%可靠)

No. Why would you expect that to work? 不,你为什么期望这样? A vector is a class. 矢量是一个类。 It is not a pointer. 它不是指针。 It just contains a pointer. 它只包含一个指针。

In the case of a vector of vectors, can I still assume this holds true? 在向量向量的情况下,我仍然可以认为这是正确的吗? I would expect the vector to hold other state data, or alignment issues, or maybe something else... 我希望矢量可以保存其他状态数据,或对齐问题,或者其他东西......

The vector behaves the same whatever you store in it. 无论你存储在哪里,矢量的行为都是一样的。 If you make a vector of vectors, you end up with an object which contains a pointer to a heap-allocated array, where each element is an object which contains a pointer to a heap-allocated array. 如果你创建了一个向量向量,最后会得到一个包含指向堆分配数组的指针的对象,其中每个元素都是一个包含指向堆分配数组的指针的对象。

As for how you should approach this, it depends on a lot of factors. 至于你应该怎么做,这取决于很多因素。 How big is your total dataset? 您的总数据集有多大? You might want to have the entire table allocated contiguously. 您可能希望连续分配整个表。 With a vector of vectors, each row is a separate allocation. 使用向量向量,每行是单独的分配。

  • Are there implementation guarantees in the stl that vector is, 在矢量是stl中是否有实现保证,
    internally, consecutive in memory 在内部,在内存中连续

Yes, it is a dynamic array. 是的,它是一个动态数组。 Standard guarantees that the objects inside vector are stored consecutively. 标准保证矢量内的对象连续存储。

  • Can I safely cast a std::vector to int* and expect that to work? 我可以安全地将std :: vector转换为int *并期望它能够工作吗?

No, but you can use begin() and use that as the pointer. 不,但你可以使用begin()并将其用作指针。

  • Are there implementation guarantees in the stl that vector is, 在矢量是stl中是否有实现保证,
    internally, consecutive in memory 在内部,在内存中连续

No, since vector may contain some internal member variables the whole 2D array will not be continuos memory location 不,因为向量可能包含一些内部成员变量,所以整个2D数组将不是连续的内存位置

Are there implementation guarantees in the stl that vector is, internally, consecutive in memory? 在stl中是否存在实现保证,向量内部是否在内存中连续?

Although I cannot quote the standards here, I have seen code in high-quality libraries assuming this layout (namely, POCO ). 虽然我不能引用这里的标准,但我已经看到了高质量库中的代码假设这种布局(即POCO )。

Can I safely cast a std::vector to int* and expect that to work? 我可以安全地将std :: vector转换为int *并期望它能够工作吗?

Specifically, you cannot recast the vector itself. 具体来说,您无法重铸矢量本身。 But, I have seen the following code: 但是,我看到了以下代码:

std::vector<int> vec;
int* ptr = &vec[0];

In the case of a vector of vectors, can I still assume this holds true? 在向量向量的情况下,我仍然可以认为这是正确的吗? I would expect the vector to hold other state data, or alignment issues, or maybe something else... 我希望矢量可以保存其他状态数据,或对齐问题,或者其他东西......

You probably cannot cast a vector of vectors to a linear array. 您可能无法将向量矢量转换为线性数组。 Each vector will reserve its own memory range and you cannot expect all of these ranges to be sequencial. 每个向量将保留自己的内存范围,您不能指望所有这些范围都是顺序的。

You mentioned in a comment that you work with up to 2500x2500xsizeof(double) data. 您在评论中提到您使用最多2500x2500xsizeof(双)数据。 In that case, I would suggest using one single vector instead of vector of vectors. 在这种情况下,我建议使用一个单一的向量而不是向量的向量。 Allocate NxM elements in a vector and wrap it in a class exposing two-dimensional indexing if you wish to. 在向量中分配NxM元素并将其包装在暴露二维索引的类中(如果您愿意)。 You get all the benefits of vector with minimum overhead and all your data is still in contiguous memory for fast processing. 您可以以最小的开销获得向量的所有好处,并且所有数据仍然在连续的内存中以便快速处理。

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

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