如何验证指向标准向量内部数组的指针

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;,

您想使用 resize,而不是 reserve,并且 size 而不是 capacityreserve 只是给向量增加了容量,实际上并没有增加大小。 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;
}

你需要了解矢量的sizecapacity的概念。 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;
}