【发布时间】:2021-09-02 10:29:57
【问题描述】:
QByteArray 使用写时复制策略,因此复制它们很便宜。我认为这也意味着可以按值传递它们。
但是,当我使用长度为零的 QByteArray 时,这个假设似乎被打破了:
struct Frame
{
QByteArray load{0, 0}; // zero size, fill with zeroes
QByteArray getLoad() { return load; }
};
Frame frame;
std::copy( frame.getLoad().begin(), frame.getLoad().end(), <somewhere> );
这有时会产生 SEGFAULT,因为 begin() 和 end() 似乎指向完全不同的位置,有时 end() 在数字上小于 begin()(这会触发 MSVC 中关于转置指针的调试验证检查)。
我目前的理解是,这是因为 frame.getLoad() 构造了一个临时的 QByteArray 两次,并且由于某种原因,它们内部的迭代器指向完全不同的位置 - 当且仅当数组大小为 0 时。
(如果数组大小为零并且实际上没有分配内存,我不确定他们应该应该指向哪里,但这对我来说仍然很令人惊讶)。
我对此的理解正确吗?如果是这样 - 我该怎么办?检查零大小的边缘情况?通过引用传递QByteArray?总是构造正确的左值数组?
附:按值返回QByteArray 的API 不是我的,它来自QCanBusFrame->payload()。
【问题讨论】:
-
frame.getLoad().begin()和frame.getLoad().end()是两个不同对象的迭代器。 -
啊哈,看起来
begin()和end()如果数组的长度为正,则可以指向重用数组,但是当长度为零时没有数组可以指向,所以有些“随机"(每个对象)值可以用于它们。 -
@MikeCAT 是的,这就是我的观点。为什么他们使用这些随机值而不是 nullptr?
-
如果您尝试 constBegin 和 constEnd,您会发现它“有效”。但是..不推荐。您应该将返回值保存在中间变量中,最好是 const,以避免 COW。
-
@Amomum 通常,不同容器的迭代器是不兼容的。容器的每个副本都是不同的容器,即使在底层实现了“写入时复制”方案。
标签: c++ qt qbytearray