RAII 字符缓冲区
RAII char buffer
我想包装几个 C 函数以安全地使用 C++。有一个 C 函数将原始指针指向数组及其大小,如 -
void function(char* bufferToFill, size_t bufsize)
现在,我无法找到可以公开要传递给此类函数的原始指针的 C++ 对象。我想避免使用 new[] 并记住在每次抛出异常时删除它。
std::string 显然不能暴露它的 char*,std::vector 类似,我唯一想到的是 std::unique_ptr 但感觉有点奇怪(因为它通常用于拥有一个对象,不是数组?)
解决此类问题的正确 C++ 方法是什么?
提前致谢
std::string obviously cant expose its char*, std::vector similar
当然可以; C++11 保证 std::string
1 和 std::vector
的存储是连续的,所以你可以做 &str[0]
来获得指向基础数据(edit:实际上 std::vector
&str[0]
如果 str.size()==0
是不行的,但是 data()
方法保证始终有效).
指针的有效性受制于通常的引用失效规则(即只要您不执行任何潜在的重新分配操作,它就是有效的)。
极端情况:空容器
虽然在这种情况下空容器不是问题(为什么有人会传递一个零长度缓冲区来填充?)了解以下内容仍然很有用:
对于std::string
,要求&str[0]
总是安全的,即使字符串为空;事实上,该标准明确表示(在 [string.access]):
Returns: *(begin() + pos)
if pos < size()
, otherwise a reference to an object of type T
with value charT()
; the referenced value shall not be modified.
对于std::vector
,可能vector为空的话调用&str[0]
是不行的; operator[]
在序列容器的一般要求中指定,具有操作语义*a.begin()
,如果size()
为0,则为未定义行为;但是,C++11 确实提供了 data()
方法,它总是 returns 某种有效指针(尽管在空向量的情况下指向空的有效范围)
不幸的是,您不能只记住 data()
对两个容器都是正确的,至于 std::string
它 returns 一个 const
指针与 c_str()
完全一样.
- 在所有答案中,我所说的
std::string
实际上指的是 std::basic_string
的任何专业化。
the only thing that comes to my mind is std::unique_ptr but it feels kinda odd (because its usually used to own an object, not array?)
这里又是一个误解。
数组是对象,the language specifically allows for std::unique_ptr
of arrays:
std::unique_ptr<int[]> p(new int[10]);
我想包装几个 C 函数以安全地使用 C++。有一个 C 函数将原始指针指向数组及其大小,如 -
void function(char* bufferToFill, size_t bufsize)
现在,我无法找到可以公开要传递给此类函数的原始指针的 C++ 对象。我想避免使用 new[] 并记住在每次抛出异常时删除它。
std::string 显然不能暴露它的 char*,std::vector 类似,我唯一想到的是 std::unique_ptr 但感觉有点奇怪(因为它通常用于拥有一个对象,不是数组?)
解决此类问题的正确 C++ 方法是什么? 提前致谢
std::string obviously cant expose its char*, std::vector similar
当然可以; C++11 保证 std::string
1 和 std::vector
的存储是连续的,所以你可以做 &str[0]
来获得指向基础数据(edit:实际上 std::vector
&str[0]
如果 str.size()==0
是不行的,但是 data()
方法保证始终有效).
指针的有效性受制于通常的引用失效规则(即只要您不执行任何潜在的重新分配操作,它就是有效的)。
极端情况:空容器
虽然在这种情况下空容器不是问题(为什么有人会传递一个零长度缓冲区来填充?)了解以下内容仍然很有用:
对于
std::string
,要求&str[0]
总是安全的,即使字符串为空;事实上,该标准明确表示(在 [string.access]):Returns:
*(begin() + pos)
ifpos < size()
, otherwise a reference to an object of typeT
with valuecharT()
; the referenced value shall not be modified.对于
std::vector
,可能vector为空的话调用&str[0]
是不行的;operator[]
在序列容器的一般要求中指定,具有操作语义*a.begin()
,如果size()
为0,则为未定义行为;但是,C++11 确实提供了data()
方法,它总是 returns 某种有效指针(尽管在空向量的情况下指向空的有效范围)
不幸的是,您不能只记住 data()
对两个容器都是正确的,至于 std::string
它 returns 一个 const
指针与 c_str()
完全一样.
- 在所有答案中,我所说的
std::string
实际上指的是std::basic_string
的任何专业化。
the only thing that comes to my mind is std::unique_ptr but it feels kinda odd (because its usually used to own an object, not array?)
这里又是一个误解。
数组是对象,the language specifically allows for std::unique_ptr
of arrays:
std::unique_ptr<int[]> p(new int[10]);