【问题标题】:casting char-array into array of PODs in C++将 char-array 转换为 C++ 中的 POD 数组
【发布时间】:2023-03-19 09:57:02
【问题描述】:

下面代码的正确写法是什么?

我有一个内存管理器,它为我提供char *,但我需要使用uint32_t 的数组。如何解决严格的别名规则?我知道对于单个对象,建议仅使用 memcpy() 复制内容,但该解决方案不适用于对象数组。

char* ptr = manager()->Allocate(1000 * sizeof(uint32_));
uint32_t* u32ptr = reinterpret_cast<uint32_t*>(ptr);
....
u32ptr[x] = y;

【问题讨论】:

  • 您的经理应该返回void*。它会解决你所有的问题(不包括)
  • 我早期的秃头问题是 10 年前。现在只是秃顶。
  • 对不起,在写这纯粹是个玩笑之前我没有看到你的个人资料照片。没有冒犯?
  • 哈哈哈 :) 无意冒犯 :)

标签: c++ c++11 pointers dynamic-memory-allocation reinterpret-cast


【解决方案1】:

你可以使用placement-new:

uint32_t* u32ptr = new(ptr) uint32_t[1000];

注意,在此之后,存储的有效类型为int32_t,您可能不再使用ptr。您不必对 chars 做任何特别的事情,因为对于具有微不足道的析构函数的类型,您可以通过重用存储来结束它们的生命周期。

【讨论】:

  • 谢谢!我怎么知道可以在大小为 X chars 的块中放置多少个整数?我猜 X 除以 sizeof (uint32_t) 是错误的..
  • char的大小按标准保证为1,所以除以sizeof(uint32_t)就可以了。
  • 是的,我的意思是 - 对齐问题。比如说,ptr 没有对齐。我猜测放置 new 将对齐整数,因此某些字节将无用。我在问是否有一种“标准”方式来知道给定指针和大小的项目数。
  • 啊好吧,现在我明白了。在 x86 上对齐从来都不是问题,对于其他情况,有一个函数可以返回最大对齐,我现在不记得了。 (让我检查...)
【解决方案2】:

您可以让Manager 类返回std::unique_ptr&lt;void, Manager::Deleter&gt;(即带有unique pointercustom deleter)。这使得分配使用 RAII 在超出范围时自动解除分配。而不是使用指针,而是更喜欢gsl::span 在这种情况下,您可以编写:

constexpr const length = 1000;
auto allocated = manager()->Allocate(
    length * sizeof(std::uint32_t), 
    alignof(uint32_t) // supporting alignment here is important, otherwise
                      // you'll have to manually take care of that yourself
);
auto p = gsl::span<uint32_t>(new(allocated.get()) std::uint32_t[length], length);

另一种选择是在元素类型上模板化 Manager 类或分配方法,并让 处理这些事情:

auto p = manager()->Allocate<std::uint32_t>(1000);

... 和 p 将是 std::unique_ptr&lt;uint32_t&gt; 到 costructed uint32_ts。并不是说您需要为它们进行任何构造,但仍然需要。

警告:在这两种情况下,您不得从您所在的范围内返回 p,因为它是一个非拥有指针,并且内存离开作用域时将被释放。 p 仅用于本地工作。如果你想保持内存超出范围,你必须return the unique_ptr

【讨论】:

  • 但是当allocated 超出范围,而p 可能仍然存在时,存储不会被回收吗?
  • @alain:当然会——除非从作用域返回unique_ptr。我将对此进行编辑以发出警告。
猜你喜欢
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-07
  • 2014-03-02
  • 2016-02-27
  • 2013-06-06
相关资源
最近更新 更多