gpt4 book ai didi

c++ - 如何以符合标准的方式方便地填充混合类型的缓冲区?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:04:40 25 4
gpt4 key购买 nike

存在一些问题,我们需要用混合类型填充缓冲区。两个例子:

  • 编程 OpenGL/DirectX,我们需要填充顶点缓冲区,它可以有混合类型(它基本上是一个结构数组,但该结构可能由运行时数据描述)
  • 创建内存分配器:将头/尾信息放入缓冲区(大小、标志、下一个/上一个指针、标记等)

问题可以这样描述:

  • 有一个分配函数,它返回一些内存(newmalloc、操作系统相关的分配函数,如 mmap虚拟分配)
  • 需要将混合类型以不同的偏移量放入分配的缓冲区

一个解决方案可以是这样的,例如将一个 int 写入一个偏移量:

void *buffer = <allocate>;
int offset = <some_offset>;
char *ptr = static_cast<char*>(buffer);
*reinterpret_cast<int*>(ptr+offset) = int_value;

但是这样很不方便,至少有两个地方有UB:

  • ptr+offset 是 UB,因为 ptr 处没有 char 数组
  • 写入 reinterpret_cast 的结果是 UB,因为那里没有 int

为了解决不方便的问题,经常使用这种方案:

union Pointer {
void *asVoid;
bool *asBool;
byte *asByte;
char *asChar;
short *asShort;
int *asInt;

Pointer(void *p) : asVoid(p) { }
};

因此,有了这个 union ,我们可以这样做:

Pointer p = <allocate>;
p.asChar += offset;
*p.asInt++ = int_value; // write an int to offset
*p.asShort++ = short_value; // then a short afterwards
// other writes here

这个方案对于填充缓冲区很方便,但是有更多的UB,因为该方案使用了非活跃的 union 成员。

所以,我的问题是:如何以一种严格符合标准且最方便的方式解决这个问题?我的意思是,我希望以符合标准的方式获得 union 解决方案提供的功能。

(注意:假设我们这里没有对齐问题,对齐是通过使用适当的偏移来处理的)

最佳答案

处理这些事情的一种简单(且一致)的方法是利用 std::memcpy将您需要的任何值移动到存储区域中的正确偏移量中,例如

std::int32_t value;
char *ptr;
int offset;
// ...
std::memcpy(ptr+offset, &value, sizeof(value));

不要担心性能,因为在许多情况下(例如小值),您的编译器实际上不会执行 std::memcpy 调用。当然,检查程序集输出(和配置文件!),但一般来说应该没问题。

关于c++ - 如何以符合标准的方式方便地填充混合类型的缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52792087/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com