如何验证指向标准向量内部数组的指针
How to validate pointer to std vector internal array
我想写入向量的内部数组。如果 vector 被初始化,我可以使用 data()
来写。
但是,如果向量为空(但有足够的存储空间),我无法直接写入向量的内部数组。
#include <vector>
#include <iostream>
using namespace std;
void write_seq(int *v, size_t len)
{
for (int i = 0; i < len; i++)
v[i] = i;
}
int main(void)
{
vector<int> v;
cout << "reserve and write\n";
v.reserve(10);
write_seq(v.data(), v.capacity());
cout << "seq length " << v.size() << "\n";
return 0;
}
输出:
$ g++ main.cpp && ./a.out
reserve and write
seq length 0
如何避免这种情况,是否可以验证向量的data()
指针?
编辑:
关于这个问题,我假设了两件事,在一个空的 vector v;
,
v.reserve(10)
为 10 个元素分配内存并且
v.data()
指向分配的内存。
您想使用 resize
,而不是 reserve
,并且 size
而不是 capacity
。 reserve
只是给向量增加了容量,实际上并没有增加大小。 resize
增加大小以匹配预留容量。
您不能分配给不存在的元素。分配内存是不够的,但是当你调整向量的大小时(或者用足够的元素创建它)你的代码是好的:
int main(void)
{
vector<int> v(10); // vector with 10 element
write_seq(v.data(), v.size()); // write to those 10 element
cout << "seq length " << v.size() << "\n"; // size is (still) 10
return 0;
}
请注意,您的代码不是很惯用。我假设您有这样做的理由,但是将迭代器传递给 write_seq
会更自然。
无需担心需要预先预留多少内存。如果性能不是真正的问题,您可以考虑使用 auto-resizable 反向插入迭代器在您想要推送元素的步骤推送元素。
#include <vector>
#include <iostream>
template<typename Iterator>
void write_seq(Iterator v) {
for (int i = 0; i < 10; i++) {
*v = i; // actually calls std::vector<>::push_back() internally
v++;
}
}
int main(void)
{
std::vector<int> v;
std::cout << "just write them data!\n";
write_seq(std::back_inserter(v));
std::cout << "seq length " << v.size() << "\n";
return 0;
}
你需要了解矢量的size
和capacity
的概念。 size 是存储的元素数量,而 capacity 是内部 space 分配的。容量总是大于或等于大小。如果向向量中插入元素并导致向量 运行 超出容量,它将通过分配当前容量两倍的新 space 自动增加其容量,然后将现有元素复制到新的 space,然后删除旧的space.
如果您计划向向量中插入大量元素,“自动增加容量”功能效率不高,因为它会不断分配新的 space 和复制元素。相反,您可以使用 reserve()
预先分配足够的 space,从而避免继续分配新的 space 的过程。
capacity():
Returns容器当前已分配space的元素数。
reserve():
将向量的容量增加到给定大小或更多。
size():
Returns容器中的元素个数。
resize():
更改存储的元素数。
回到你的问题,你可以简单地将reserve
替换为resize
:
int main(void)
{
vector<int> v;
cout << "reserve and write\n";
v.resize(10); // use resize() instead of reserve()
write_seq(v.data(), v.size());
cout << "seq length " << v.size() << "\n";
return 0;
}
或者,您可以直接插入到向量中:
void write_seq(vector<int>& v, size_t len)
{
for (int i = 0; i < len; i++)
v.push_back(i); // add an element to the vector, this changes the size
}
int main(void)
{
vector<int> v;
cout << "reserve and write\n";
v.reserve(10); // this does not change size, the vector is still empty
write_seq(v, v.capacity());
cout << "seq length " << v.size() << "\n";
return 0;
}
我想写入向量的内部数组。如果 vector 被初始化,我可以使用 data()
来写。
但是,如果向量为空(但有足够的存储空间),我无法直接写入向量的内部数组。
#include <vector>
#include <iostream>
using namespace std;
void write_seq(int *v, size_t len)
{
for (int i = 0; i < len; i++)
v[i] = i;
}
int main(void)
{
vector<int> v;
cout << "reserve and write\n";
v.reserve(10);
write_seq(v.data(), v.capacity());
cout << "seq length " << v.size() << "\n";
return 0;
}
输出:
$ g++ main.cpp && ./a.out
reserve and write
seq length 0
如何避免这种情况,是否可以验证向量的data()
指针?
编辑:
关于这个问题,我假设了两件事,在一个空的 vector v;
,
v.reserve(10)
为 10 个元素分配内存并且v.data()
指向分配的内存。
您想使用 resize
,而不是 reserve
,并且 size
而不是 capacity
。 reserve
只是给向量增加了容量,实际上并没有增加大小。 resize
增加大小以匹配预留容量。
您不能分配给不存在的元素。分配内存是不够的,但是当你调整向量的大小时(或者用足够的元素创建它)你的代码是好的:
int main(void)
{
vector<int> v(10); // vector with 10 element
write_seq(v.data(), v.size()); // write to those 10 element
cout << "seq length " << v.size() << "\n"; // size is (still) 10
return 0;
}
请注意,您的代码不是很惯用。我假设您有这样做的理由,但是将迭代器传递给 write_seq
会更自然。
无需担心需要预先预留多少内存。如果性能不是真正的问题,您可以考虑使用 auto-resizable 反向插入迭代器在您想要推送元素的步骤推送元素。
#include <vector>
#include <iostream>
template<typename Iterator>
void write_seq(Iterator v) {
for (int i = 0; i < 10; i++) {
*v = i; // actually calls std::vector<>::push_back() internally
v++;
}
}
int main(void)
{
std::vector<int> v;
std::cout << "just write them data!\n";
write_seq(std::back_inserter(v));
std::cout << "seq length " << v.size() << "\n";
return 0;
}
你需要了解矢量的size
和capacity
的概念。 size 是存储的元素数量,而 capacity 是内部 space 分配的。容量总是大于或等于大小。如果向向量中插入元素并导致向量 运行 超出容量,它将通过分配当前容量两倍的新 space 自动增加其容量,然后将现有元素复制到新的 space,然后删除旧的space.
如果您计划向向量中插入大量元素,“自动增加容量”功能效率不高,因为它会不断分配新的 space 和复制元素。相反,您可以使用 reserve()
预先分配足够的 space,从而避免继续分配新的 space 的过程。
capacity():
Returns容器当前已分配space的元素数。
reserve():
将向量的容量增加到给定大小或更多。
size():
Returns容器中的元素个数。
resize():
更改存储的元素数。
回到你的问题,你可以简单地将reserve
替换为resize
:
int main(void)
{
vector<int> v;
cout << "reserve and write\n";
v.resize(10); // use resize() instead of reserve()
write_seq(v.data(), v.size());
cout << "seq length " << v.size() << "\n";
return 0;
}
或者,您可以直接插入到向量中:
void write_seq(vector<int>& v, size_t len)
{
for (int i = 0; i < len; i++)
v.push_back(i); // add an element to the vector, this changes the size
}
int main(void)
{
vector<int> v;
cout << "reserve and write\n";
v.reserve(10); // this does not change size, the vector is still empty
write_seq(v, v.capacity());
cout << "seq length " << v.size() << "\n";
return 0;
}