std::vector、char * 和 C API

std::vector, char *, and C API

提问人:Uy Hà 提问时间:3/7/2022 最后编辑:Uy Hà 更新时间:3/7/2022 访问量:400

问:

我想使用一些需要缓冲区的 C API,我正在考虑将其用作 backer 缓冲区。我现在的想法是charstd::vector

  • 获取 C API 所需的大小
  • 创建一个矢量并相应地保留其大小
  • 将向量馈送到 C API
  • 获取 C API 写入的字节数
  • 相应地调整矢量大小

以下代码概述了这个想法:

int main(){
  auto required_size = get_required_buffer_size();

  auto buffer = std::vector<char>{};
  buffer.resize(required_size);

  auto read_size = read_data(std::data(buffer), buffer.capacity());
  buffer.resize(read_size);
}

这是 的正确用法,还是我在某个地方搬起石头砸自己的脚?std::vector

编辑:更改为自上次以来将覆盖写入的数据reserveresizeresizeread_data

C++ 矢量 标准

评论

3赞 UnholySheep 3/7/2022
为什么不直接打电话而不是做一个和一个?事实上,我希望代码按原样覆盖由于读取数据后的调用而导致的内容buffer.resize(required_size);reserveresizebufferresize
2赞 Ted Lyngmo 3/7/2022
@UyHà 常用方法是在读取前达到所需的大小,在读取达到实际读取的字节数。使用和越界写入 (>= ) 会使程序具有未定义的行为。resize()resize()reservesize()
1赞 Ted Lyngmo 3/7/2022
@MatG 你会有 UB,至少在 g++ 和 clang++ 中,如果你向上,你将无法看到你读取的数据。resize()
1赞 Ted Lyngmo 3/7/2022
@MatG 即使您预留了足够的空间,在缓冲区中的位置写入也是 UB。>= size()
1赞 MatG 3/7/2022
@TedLyngmo 我天真地认为,如果是基本类型,就不会有风险,但我错了(但幸运的是,我检查过我从未这样做过,我总是选择一个非常简单的自定义类)。TDynamicBuffer<>

答:

2赞 Remy Lebeau 3/7/2022 #1

你所拥有的非常接近,但它可以使用一些微妙的变化:

auto buffer = std::vector<char>{};
buffer.resize(required_size);

可以减少到

std::vector<char> buffer(required_size);

并且需要是 or .buffer.capacity()required_sizebuffer.size()

int main(){
  auto required_size = get_required_buffer_size();

  std::vector<char> buffer(required_size);

  auto read_size = read_data(buffer.data(), buffer.size());
  buffer.resize(read_size);
}

话虽如此,在需要缓冲区的情况下,我更喜欢使用:char[]std::string

int main(){
  auto required_size = get_required_buffer_size();

  std::string buffer(required_size, '\0');

  auto read_size = read_data(buffer.data()/*or: &buffer[0]*/, buffer.size());
  buffer.resize(read_size);
}

评论

0赞 Uy Hà 3/7/2022
缓冲区更像是原始字节缓冲区,而不是真正的字符串,这就是为什么我更喜欢std::vectorstd::string
0赞 Remy Lebeau 3/7/2022
原始字节应使用 或 表示unsigned charstd::byte
0赞 Uy Hà 3/8/2022
不过,这不是 C API 想要的
0赞 Remy Lebeau 3/8/2022
在将指针传递给 C API 时,没有什么能阻止您强制转换指针。unsigned char*char*
0赞 Uy Hà 3/8/2022
是的,但这只是更麻烦,我真的看不出它有什么优势