零大小的 QByteArray; begin() 和 end() 指向哪里?
QByteArray of zero size; where do begin() and end() point to?
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
?始终构造适当的左值数组?
P.S。 API 按值返回 QByteArray
不是我的,它来自 QCanBusFrame->payload()
.
您在 std::copy
的呼叫中呼叫了 frame.getLoad()
两次。他们会 return 不同 QByteArray
,所以他们的 begin()
和 end()
没有关系。
你可以getLoad()
return参考load
来克服这个问题。
QByteArray& getLoad() { return load; }
如果您想要 getLoad()
return load
的副本,您应该在调用 std::copy
并使用它之前将其存储到一个变量中。
Frame frame;
QByteArray frameLoad = frame.getLoad();
std::copy( frameLoad.begin(), frameLoad.end(), <somewhere> );
“写入时复制”意味着它将在写入 之前复制。现在,当您调用 begin()
时,它 returns 您是一个迭代器,您可以使用它 将 写入容器而容器不知情。那么,class 应该怎么做才能避免(可能)使共享状态无效?它应该复制整个东西。这就是你的情况。你得到 2 个副本,以及指向不同缓冲区的迭代器。
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
?始终构造适当的左值数组?
P.S。 API 按值返回 QByteArray
不是我的,它来自 QCanBusFrame->payload()
.
您在 std::copy
的呼叫中呼叫了 frame.getLoad()
两次。他们会 return 不同 QByteArray
,所以他们的 begin()
和 end()
没有关系。
你可以getLoad()
return参考load
来克服这个问题。
QByteArray& getLoad() { return load; }
如果您想要 getLoad()
return load
的副本,您应该在调用 std::copy
并使用它之前将其存储到一个变量中。
Frame frame;
QByteArray frameLoad = frame.getLoad();
std::copy( frameLoad.begin(), frameLoad.end(), <somewhere> );
“写入时复制”意味着它将在写入 之前复制。现在,当您调用 begin()
时,它 returns 您是一个迭代器,您可以使用它 将 写入容器而容器不知情。那么,class 应该怎么做才能避免(可能)使共享状态无效?它应该复制整个东西。这就是你的情况。你得到 2 个副本,以及指向不同缓冲区的迭代器。