RAII字符缓冲区

RAII char buffer

本文关键字:缓冲区 字符 RAII      更新时间:2023-10-16

为了安全使用C++,我想包装一些C函数。有一个C函数,它获取指向数组及其大小的原始指针,如-

void function(char* bufferToFill, size_t bufsize)

现在,我很难找到C++对象,它可以公开要传递给这样的函数的原始指针。我希望避免使用new[],并记住每次抛出异常时都要删除它。

std::string显然无法公开其char*,std::vector类似,我脑海中唯一想到的是std::unique_ptr,但它感觉有点奇怪(因为它通常用于拥有对象,而不是数组?)

用C++解决这样的问题的正确方法是什么?提前感谢

我唯一想到的是std::unique_ptr,但它感觉有点奇怪(因为它通常用于拥有对象,而不是数组?)

这里还有一个误解。

数组是一个对象,该语言专门允许数组的std::unique_ptr

std::unique_ptr<int[]> p(new int[10]);

std::string显然不能暴露其char*,std::vector类似

他们当然可以;C++11保证std::string1std::vector的存储是连续的,因此您可以执行&str[0]以获得指向底层数据的指针(edit:实际上,对于std::vector,如果str.size()==0&str[0]是不可以的,但是data()方法保证始终工作)。

指针的有效性受通常引用无效规则的约束(即,只要不执行任何潜在的重新分配操作,指针就有效)。

角落案例:空容器

虽然在这种情况下,空容器不是问题(为什么有人会传递零长度的缓冲区来填充?)但知道这一点仍然很有用:

  • 对于std::string,请求&str[0]总是安全的,即使字符串为空;事实上,标准明确表示(在[string.access]):

    返回:如果为pos < size(),则返回*(begin() + pos),否则返回对值为charT()T类型对象的引用;不得修改参考值。

  • 对于std::vector,如果向量为空,那么调用&str[0]可能是不好的;operator[]是在序列容器的一般要求中指定的,具有操作语义*a.begin(),如果size()为0,则为未定义行为;然而,C++11确实提供了data()方法,它总是返回某种有效指针(尽管在空向量的情况下是空的有效范围)

不幸的是,您不能只记住data()对于两个容器都是正确的,因为对于std::string,它返回的const指针与c_str()完全一样。


  1. 在所有的答案中,我说的std::string实际上指的是std::basic_string的任何专业化