我想写一些字节到一个数组。为了使用现代C++,我决定使用智能指针。
#include <memory>
#include <cstdint>
using namespace std;
void writeUint32_t(uint32_t value, unsigned char* p){
*p = static_cast<unsigned char>((value >> 24) & 0xFF);
*(++p) = static_cast<unsigned char>((value >> 16) & 0xFF);
*(++p) = static_cast<unsigned char>((value >> 8) & 0xFF);
*(++p) = static_cast<unsigned char>((value ) & 0xFF);
}
int main(){
auto buf = make_shared<unsigned char[]>(512);
uint32_t data = 1234;
writeUint32_t(data, buf.get() + 8);
}
但是,我收到了以下编译错误:
u.cpp:15:37: error: invalid use of array with unspecified bounds
writeUint32_t(data, buf.get() + 8);
^
u.cpp:15:38: error: cannot convert ‘unsigned char (*)[]’ to ‘unsigned char*’ for argument ‘2’ to ‘void writeUint32_t(uint32_t, unsigned char*)’
writeUint32_t(data, buf.get() + 8);
我正在使用g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609
在这种情况下有没有使用智能指针的方法?
5条答案
按热度按时间ktca8awb1#
不要在raw array中使用
std::make_shared
,它不会像你期望的那样构造一个数组,而是会尝试创建一个指向你指定的类型的指针,即unsigned char[]
。这就是为什么当你使用get()
时会得到一个unsigned char (*)[]
,正如错误消息所说。而且
std::shared_ptr
默认会删除指针delete
,而不是delete[]
,应该是数组使用的。您需要为它指定一个自定义的删除器,但std::make_shared
不允许您指定它。您可以(1)直接初始化
std::shared_ptr
并指定删除器,如(2)使用
std::unique_ptr
,它为数组提供了指定的版本,包括在解除分配时调用delete[]
,并提供operator[]
(std::shared_ptr
将在C++17中支持)。(3)考虑
std::vector<unsigned char>
和std::array<unsigned char>
。dgtucam12#
我建议您使用
std::vector<unsigned char> vec(512);
, Package 连续动态数组正是它的用途。获取原始缓冲区指针就像vec.data()
一样简单;如果向量需要共享,那么您仍然可以使用智能指针
您将获得引用计数的好处,由于使用vector,几乎没有开销,和您将获得整个vector API。
bttbmeg03#
如果你真的想使用一个
shared_ptr
和一个数组(而不是StoryTeller建议的向量),你的类型应该是unsigned char
而不是unsigned char[]
。为了确保数组被正确删除,你需要指定一个数组删除器传递给shared_ptr
构造函数(所以你不能使用make_shared
,因为这不允许你指定删除器):guykilcj4#
您不能用途:
这是因为
Type[]
没有 * 模板专门化 *。这是因为实际上std::shared_ptr<T>
还不支持operator[]
。在新标准 C++17 中:operator[](C++17)
一个解决方案可能是使用 *STL容器 *,或IMO更好:
std::unique_ptr
。std::unique_ptr
支持operator[]
。它是异常安全的,开销几乎为0,并且可以用作数组缓冲区。
此外,通过正确调用
delete[]
运算符,可以正确处理缓冲区的释放。8aqjt8rx5#
如果你真的需要
shared_ptr<T[]>
而不是unique_ptr<T[]>
,我建议你使用boost::shared_ptr
。支持T[]
。优点:
shared_ptr<T[]>
。尝试g 11.3和VS2022。1.使用
std::shared_ptr<T>(new T[size], deleter)
表达式创建数组效率不高,因为引用计数器的内存被分配到了其他地方。std::shared_ptr<std::vector>
也不是有效的,因为shared_ptr指向指针。为了访问数据,您需要再次取消引用。boost::shared_ptr
解决了所有问题:1.用于数据和引用计数器的存储器是一次性分配的,并且是在附近分配的,这提高了数据局部性
shared_ptr
指向数据本身,而不是像std::vector
那样指向另一个指针以下是一个片段: