C++ C++;:获取std::vector的起始地址?

C++ C++;:获取std::vector的起始地址?,c++,pointers,vector,C++,Pointers,Vector,有时,使用std::vector的起始地址并临时将该地址视为定期分配的缓冲区的地址非常有用。 例如: char* buf = new char[size]; fillTheBuffer(buf, size); useTheBuffer(buf, size); delete[] buf; 为此: vector<char> buf(size); fillTheBuffer(&buf[0], size); useTheBuffer(&buf[0], size

有时,使用
std::vector的起始地址并临时将该地址视为定期分配的缓冲区的地址非常有用。
例如:

 char* buf = new char[size];
 fillTheBuffer(buf, size);
 useTheBuffer(buf, size);
 delete[] buf;
为此:

 vector<char> buf(size);
 fillTheBuffer(&buf[0], size);
 useTheBuffer(&buf[0], size);
向量buf(大小);
填充缓冲区(&buf[0],大小);
使用缓冲区(&buf[0],大小);
这样做的好处当然是自动释放缓冲区,我不必担心
delete[]

我遇到的问题是当size==0时。在这种情况下,第一个版本可以正常工作。空缓冲区被“分配”,后续函数不执行任何操作,它们得到的大小=0。
但是,如果size==0,则第二个版本将失败,因为调用
buf[0]
可能正确地包含
0
的断言

那么,除了成语
&buf[0]
之外,还有没有其他方法可以返回向量开头的地址,即使向量是空的


我也考虑过使用
buf.begin()
,但根据标准,它甚至不能保证返回指针。

我想您只需要检查一下

也许是一个实用功能:

template <class T, class Alloc>
T* data(std::vector<T, Alloc>& vec)
{
    return vec.empty() ? 0 : &vec[0];
}

template <class T, class Alloc>
const T* data(const std::vector<T, Alloc>& vec)
{
    return vec.empty() ? 0 : &vec[0];
}
模板
T*数据(标准::向量和向量)
{
返回vec.empty()?0:&vec[0];
}
模板
常数T*数据(常数标准::向量和向量)
{
返回vec.empty()?0:&vec[0];
}

虽然
std::basic_string
数据()
可以满足您的需要,但没有相应的函数


您必须使用类似于
buf.size()?&buf[0]:0

我认为无论哪种情况,你都应该是安全的。我认为vector::operator[int]和vector::at(int)之间的区别在于[]操作符重载并没有执行边界检查。使用buf[0]应该没有断言

如果您可以更改fillTheBuffer并使用Buffer获取一对迭代器,那么您将以标准库解决问题的方式解决问题。

这看起来像是STL库中的一个疏忽。C++允许你分配<代码>新的T[ 0 ] < /> >,并为这种情况返回有效指针,但是STL的大多数实现仅在你分配给该元素或某物的情况下断言。它如何知道<代码>和BUF(0)< /C>和<代码> BUF(0)之间的区别。=1
?第一句话:如果
T
有一个重载的
&
操作符,是否值得投资于
boost::addressof
?第二条备注:第二个模板参数
Alloc
将使函数更通用。@Matthieu:关于第一条备注:。不能存储
&t
未返回其地址的类型。-第二句话补充了答案。很遗憾,你错了。MSVC2008的vector有关于
运算符[]
的断言。作为后续操作,我了解到以下
\define\u SECURE\u SCL 0
将禁用此行为。