C++ 如何访问std::vector的内部连续缓冲区,以及如何将其与memcpy等一起使用?

C++ 如何访问std::vector的内部连续缓冲区,以及如何将其与memcpy等一起使用?,c++,stl,vector,C++,Stl,Vector,如何访问std::vector中使用的连续内存缓冲区,以便对其执行直接内存操作(例如memcpy)?此外,在该缓冲区上执行memcpy之类的操作是否安全 我已经读到该标准保证向量在内部使用连续内存缓冲区,但它不一定实现为动态数组。我想如果它确实是连续的,我应该可以这样使用它——但我不确定向量实现是否将簿记数据存储为该缓冲区的一部分。如果出现这种情况,则类似于memcpying向量缓冲区的操作会破坏其内部状态。是-由于标准保证了向量的内部数据的连续放置,因此您可以通过以下方式访问指向向量中第一个元

如何访问std::vector中使用的连续内存缓冲区,以便对其执行直接内存操作(例如memcpy)?此外,在该缓冲区上执行memcpy之类的操作是否安全


我已经读到该标准保证向量在内部使用连续内存缓冲区,但它不一定实现为动态数组。我想如果它确实是连续的,我应该可以这样使用它——但我不确定向量实现是否将簿记数据存储为该缓冲区的一部分。如果出现这种情况,则类似于memcpying向量缓冲区的操作会破坏其内部状态。

是-由于标准保证了
向量的内部数据的连续放置,因此您可以通过以下方式访问指向向量中第一个元素的指针:

std::vector<int> my_vector;
// initialize...

int* arr = &my_vector[0];
std::vector my_vector;
//初始化。。。
int*arr=&my_向量[0];
简单地做

&vec[0];

// or Goz's suggestion:
&vec.front();

// or
&*vec.begin();
// but I don't know why you'd want to do that
这将返回向量中第一个元素的地址(假设
vec
包含超过
0
个元素),这是它使用的数组的地址<代码>向量
存储由标准保证是连续的,因此这是一种安全的方法,可以将向量与期望数组的函数一起使用

请注意如果您添加或删除向量中的元素,或[可能]以任何方式修改向量(例如调用
reserve
),此指针可能会无效并指向内存的解除分配区域

&myvec[0]

但是请注意,使用
memcpy
实际上只适用于POD或基元类型的向量。对任何其他内容进行直接内存操作都会导致未定义的行为。

最简单的方法是使用
&v[0]
,其中v是向量。例如:

int write_vector(int fd, const std::vector<char>& v) {
   int rval = write(fd, &v[0], v.size());
   return rval;
}
int写向量(int-fd,const-std::vector&v){
int rval=write(fd,&v[0],v.size());
返回rval;
}

实际上,几乎所有编译器都将
向量
实现为一个隐藏的数组。您可以通过执行
&somevector[0]
获得指向此数组的指针。如果向量的内容是POD(“Prime- Dead DATA”)类型,那么,执行<代码> MeMCPY 应该是安全的,但是如果它们是具有复杂初始化逻辑的C++类,则使用起来更安全。

可以简单地做:

  &vect[0]
内存保证是连续的,因此使用C库函数(如memcpy)使用它是安全的。但是,您不应该将指针持久化到连续数据中,因为向量大小调整可能会重新分配内存并将其复制到其他位置。也就是说,以下情况会很糟糕:

  std::vector<char> charVect;
  // insert a bunch of stuff into charVect
  ...
  char* bufferPtr = &charVect[0];
  charVect.push_back('a'); // potential resize
  // Now bufferPtr may not be valid since the resize may have moved
  // the vectors contents
  bufferPtr[0] = 'f'; // **CRASH**
std::vector charVect;
//在charVect中插入一堆东西
...
char*bufferPtr=&charVect[0];
charVect.push_back('a');//潜在调整大小
//现在bufferPtr可能无效,因为调整大小可能已移动
//矢量内容
bufferPtr[0]=“f”;//**撞车**

虽然您可以安全地从底层存储中读取正确数量的数据,但根据设计,在底层存储中写入数据可能不是一个好主意

    vlad:Code ⧴ cat vectortest.cpp
    #include <vector>
    #include <iostream>
    int main()
    {
        using namespace std;
        vector<char> v(2);
        v.reserve(10);
        char c[6]={ 'H', 'e', 'l', 'l', 'o', '\0' };
        cout << "Original size is " << v.size();
        memcpy( v.data(), c, 6);
        cout << ", after memcpy it is " << v.size();
        copy(c, c+6, v.begin());
        cout << ", and after copy it is " << v.size() << endl;
        cout << "Arr: " << c << endl;
        cout << "Vec: ";
        for (auto i = v.begin(); i!=v.end(); ++i) cout << *i;
        cout << endl;
    }
    vlad:Code ⧴ make vectortest
    make: `vectortest' is up to date.
    vlad:Code ⧴ ./vectortest
    Original size is 2, after memcpy it is 2, and after copy it is 2
    Arr: Hello
    Vec: He
    vlad:Code ⧴
vlad:code⧴ cat vectortest.cpp
#包括
#包括
int main()
{
使用名称空间std;
向量v(2);
v、 储备(10);
字符c[6]={'H','e','l','l','o','\0'};

@Bo不可能重复,可能不是dup,因为这里的OP特别询问C std lib函数,而链接的问题不是。dup显示
char*p=&vc[0]
作为获取缓冲区的方式。然后呢?或者&vec.front()这比上面的begin方法好得多;)Nps:)我倾向于使用它而不是使用&vec[0],因为它使我使用的向量更明显:)为什么不使用vec.data()?标准保证向量是连续块。