使用 C++ 容器和智能指针而不是 C 样式数组作为缓冲区有缺点吗?

问题描述 投票:0回答:1

我经常看到,当 C++ 函数想要返回数据缓冲区时,调用者必须提供指向缓冲区第一个元素的指针和计数作为函数参数。有时这是有意义的,因为函数的返回值用于传达函数的结果。但是我们不能只使用像 std::vector 或 std::array 这样的 STL 容器在函数中创建数据集合并返回指向该数据的指针吗?

如果我们考虑CNG API中的

BcryptGenRandom()
方法,

NTSTATUS BCryptGenRandom(
  [in, out] BCRYPT_ALG_HANDLE hAlgorithm,
  [in, out] PUCHAR            pbBuffer,
  [in]      ULONG             cbBuffer,
  [in]      ULONG             dwFlags
);

我可以将此函数与“现代 C++”功能一起使用:

//Method 1
#include <iostream>
#include <cstdint>
#include <memory>
#include <array>
#include <exception>

#include <Windows.h>
#include <bcrypt.h>

#define NT_SUCCESS(Status)  (((NTSTATUS)(Status)) >= 0)

template <ULONG N>
std::shared_ptr<std::array<BYTE, N>> GenRandom()
{
    std::shared_ptr<std::array<BYTE, N>> pBuffer{ new std::array<BYTE, N> };
    if (!NT_SUCCESS(BCryptGenRandom(NULL, pBuffer->data(), pBuffer->size(), BCRYPT_USE_SYSTEM_PREFERRED_RNG)))
    {
        throw std::exception();
    }
    
    return pBuffer;
}

int main() {
    const int size{ 64 };
    std::shared_ptr<std::array<BYTE, size>> arr{};
    try
    {
        arr = GenRandom<size>();
    }
    catch (const std::exception& ex)
    {
        return 1;
    }

    for (int i{ 0 }; i < arr->size(); i++)
    {
        std::cout << std::hex << static_cast<std::uint16_t>((*arr)[i]);
    }
    return 0;
}

或者以大多数文档和教程中出现的老式方式:

//Method 2
int main() {
    const int size{ 64 };
    BYTE buffer[size]{};
    if (!NT_SUCCESS(BCryptGenRandom(NULL, buffer, size, BCRYPT_USE_SYSTEM_PREFERRED_RNG)))
    {
        return 1;
    }

    for (int i{ 0 }; i < size; i++)
    {
        std::cout << std::hex << static_cast<std::int16_t>(buffer[i]);
    }
    return 0;
}

尽管第二种方法看起来更简单、更直接,但我总觉得第一种方法提供了更好的封装和错误处理机制,同时智能指针负责释放动态分配的内存(例如:当我要使用这个

GenRandom()
方法可以在代码库的不同位置生成任意大小的随机值)。

那么,在使用缓冲区时,与第二种方法相比,第一种方法在性能、兼容性或我所遗漏的方面是否有任何重大缺点?

c++ stl buffer
1个回答
0
投票

智能指针的目的是取代手动内存管理(

new
/
delete
,或
malloc
/
free
)。 如果这是一个可行的选择来写

BYTE buffer[size]{};

...那么使用智能指针(尤其是

std::shared_ptr
)完全没有意义,除了浪费性能之外什么也没有。编译器已经自动为您管理内存,将其包装在智能指针中并不会让这段代码变得更好。

但是,如果您看到 C 风格数组的现代替代方案,那就是

std::array

std::array<BYTE, size> buffer{};

另请参阅:std::array 与数组性能

© www.soinside.com 2019 - 2024. All rights reserved.