我知道标准不会强制 std::vector 分配连续的内存块,但所有实现仍然遵循这一点。
假设我希望创建一个多维静态数组的向量。为简单起见,考虑 2 维和长度为 N 的向量。也就是说,我希望创建一个具有 N 个元素的向量,例如 int[5]
。
我能否确定所有 N*5 整数现在在内存中都是连续的?这样我原则上就可以通过知道第一个元素的地址来访问所有整数?这个实现依赖吗?
作为参考,我目前在连续内存块中创建 2D 数组的方式是首先创建一个长度为 N 的 float* 的(动态)数组,在一个数组中分配所有 N*5 个浮点数,然后将每 5 个元素的地址复制到float*
的第一个数组。
I know that the standard does not force std::vector
to allocate contiguous memory blocks, but all implementations obey this nevertheless.
Suppose I wish to create a vector of a multidimensional, static array. Consider 2 dimensions for simplicity, and a vector of length N. That is I wish to create a vector with N elements of, say, int[5]
.
Can I be certain that all N*5 integers are now contiguous in memory? So that I in principle could access all of the integers simply by knowing the address of the first element? Is this implementation dependent?
For reference the way I currently create a 2D array in a contiguous memory block is by first making a (dynamic) array of float* of length N, allocating all N*5 floats in one array and then copying the address of every 5th element into the first array of float*
.
发布评论
评论(6)
标准确实需要
std::vector
的内存连续的。另一方面,如果您编写如下内容:
全局内存(所有
v[i][j]
)将不是连续的。这创建二维数组的常用方法是使用单个
数组并计算索引,正如您建议使用 float 所做的那样。
(您还可以使用地址创建第二个
std::vector
如果你想。然而,我总是只是重新计算索引。)
The standard does require the memory of an
std::vector
to becontiguous. On the other hand, if you write something like:
the global memory (all of the
v[i][j]
) will not be contiguous. Theusual way of creating 2D arrays is to use a single
and calculate the indexes, exactly as you suggest doing with
float
.(You can also create a second
std::vector<float*>
with the addressesif you want. I've always just recalculated the indexes, however.)
正如 @Als 已经指出的那样,是的,std::vector(现在)保证了连续分配。然而,我不会用指针数组模拟二维矩阵。相反,我建议采用两种方法之一。 (到目前为止)更简单的是仅使用
operator()
进行下标,并进行乘法将 2D 输入转换为向量中的线性地址:如果出于某种原因,您想要使用
matrix[a][b]
样式寻址,可以使用代理类来处理转换。虽然它是针对 3D 矩阵而不是 2D,但我在 上一个答案。As @Als already pointed out, yes,
std::vector
(now) guarantees contiguous allocation. I would not, however, simulate a 2D matrix with an array of pointers. Instead, I'd recommend one of two approaches. The simpler by (by far) is to just useoperator()
for subscripting, and do a multiplication to convert the 2D input to a linear address in your vector:If, for whatever reason, you want to use
matrix[a][b]
style addressing, you can use a proxy class to handle the conversion. Though it was for a 3D matrix instead of 2D, I posted a demonstration of this technique in previous answer.根据 C++ 标准,Vector 的元素保证是连续的。
标准引用如下:
From n2798 (C++0x 草案):
23.2.6 类模板向量 [向量]
1 向量是支持随机访问迭代器的序列容器。此外,它还支持末尾(摊销)恒定时间插入和擦除操作;中间的插入和擦除需要线性时间。存储管理是自动处理的,但可以给出提示以提高效率。向量的元素是连续存储的,这意味着如果 v 是一个向量,其中 T 是 bool 以外的某种类型,那么对于所有 0 < ,它遵循恒等式 &v[n] == &v[0] + n ;= n < v.size()。
C++03 标准 (23.2.4.1):
向量的元素是连续存储的,这意味着如果v 是一个向量,其中 T 是 bool 以外的某种类型,那么对于所有 0 <= n < ,它遵循恒等式 &v[n] == &v[0] + n v.size()。
另外,请参阅这里赫伯·萨特对此的看法。
Elements of a Vector are gauranteed to be contiguous as per C++ standard.
Quotes from the standard are as follows:
From n2798 (draft of C++0x):
23.2.6 Class template vector [vector]
1 A vector is a sequence container that supports random access iterators. In addition, it supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage management is handled automatically, though hints can be given to improve efficiency. The elements of a vector are stored contiguously, meaning that if v is a vector where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
C++03 standard (23.2.4.1):
The elements of a vector are stored contiguously, meaning that if v is a vector where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
Also, see here what Herb Sutter's views on the same.
这不是一个二维数组,而是一个指针数组。如果您想要一个真正的二维数组,那么它是如何完成的:
请注意,只有一个分配。我可以建议您阅读有关在 C++ 中使用数组的更多信息吗?
That's not a 2D array, that's an array of pointers. If you want a real 2D array, this is how it's done:
Note there is only a single allocation. May I suggest reading more about using arrays in C++?
在底层,向量可能看起来大约类似于(p 代码):
现在,如果您创建一个
vector >
,将会有这样的布局或“内联”形式的
布局是的,向量-向量因此使用连续的内存,但是不,不是你想要的那样。它很可能存储指向外部位置的指针数组(以及一些其他变量)。
该标准只要求向量的数据是连续的,而不是向量作为一个整体。
Under the hood, a vector may look approximately like (p-code):
Now if you make a
vector<vector<T> >
, there will be a layout like thisor in "inlined" form
Yes, the vector-vector therefore uses contiguous memory, but no, not as you'd like it. It most probably stores an array of pointers (and some other variables) to external places.
The standard only requires that the data of a vector is contiguous, but not the vector as a whole.
创建一个简单的类,如您所说的,二维数组,类似于:
可以这样使用:
或者甚至传递
&myArray[0][0]< /code> 作为采用某种“平面缓冲区”的低级函数的地址。
但正如您所看到的,它扭转了天真的期望,因为它是 myarray[y][x]。
一般来说,如果您与需要某种经典 C 风格平面数组的代码交互,那么为什么不直接使用它呢?
编辑:如上所述,上面的内容很简单。没有任何边界检查尝试。就像“数组”一样。
A simple class to create, as you call it, a 2D array, would be something like:
It's possible to use this like:
Or even pass
&myArray[0][0]
as address to low-level functions that take some sort of "flat buffers".But as you see, it turns naive expectations around in that it's
myarray[y][x]
.Generically, if you interface with code that requires some sort of classical C-style flat array, then why not just use that ?
Edit: As said, the above is simple. No bounds check attempts whatsoever. Just like, "an array".