c++ - 通过 make_shared 用 shared_ptr 包装动态数组

标签 c++ arrays shared-ptr smart-pointers

我想将一些字节写入数组。为了使用现代 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 有没有办法在这种情况下使用智能指针?

最佳答案

不要使用 std::make_shared 对于原始数组,它不会像您预期的那样构造一个数组,但会尝试创建一个指向您指定类型的指针,即 unsigned char[] .这就是为什么你得到 unsigned char (*)[]使用时get() ,如错误消息所述。

std::shared_ptr 将通过 delete 删除指针默认情况下,不是 delete[] ,应该用于数组。你需要为它指定一个定制的删除器,但是std::make_shared不允许您指定它。

您可以 (1) 初始化 std::shared_ptr直接指定删除器,比如

std::shared_ptr<unsigned char> buf(new unsigned char[512], [](unsigned char* p)
{
    delete[] p;
}); 

(2) 使用 std::unique_ptr 相反,它为数组提供指定版本,包括调用 delete[]解除分配和提供时 operator[] (std::shared_ptr 将从 C++17 开始支持它)。

auto buf = std::make_unique<unsigned char[]>(512);

(3) 考虑std::vector<unsigned char>std::array<unsigned char> .

关于c++ - 通过 make_shared 用 shared_ptr 包装动态数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39142343/

相关文章:

c++ - 哪个 union 成员在安置新人后变得活跃

c++ - std::shared_ptr 删除器类型

c++ - 将(共享指针的) vector 的值分配给共享指针导致段错误c++

c++ - 如何使用AfxMessageBox打印符号 "↑"?

c++ - 有没有插入然后排序的替代方法

c++ - MySQL C++ 连接器更新

PHP Ajax 分页数组不起作用

php - 计算特定值在数组中出现的频率

java - 查找整数数组中存在的整数的最大镜像 [CodingBat 谜语 : MaxMirror]

c++ - `std::shared_ptr` 的智能指针模拟,带有用于将回调绑定(bind)到引用计数修改事件的 API,例如释放/保留……这是一回事吗?