我正在审查一些代码(无法发布全部代码),但是有一个像这样的函数:
template <typename DestType, typename SourceType>
inline void transferDataAndUpdateSpan(MyArray<DestType>& to, MySpan<const SourceType>& source)
{
static_assert(sizeof(DestType) == sizeof(SourceType), "Data size mismatch!!");
to.resize(source.size());
memcpy(to.data(), source.data(), sizeof(SourceType) * source.size());
source = { (SourceType*)to.data(), to.size() };
}
MySpan
基本上是 std::span
的 typedef,而 MyArray
是一个容器,它有一个构造函数,该构造函数接收指向数据的指针和数据大小。
问题:
source = { (SourceType*)to.data(), to.size() };
是否打破了严格的别名?
这是触发UB吗?
看这段代码:
to.resize(source.size());
memcpy(to.data(), source.data(), sizeof(SourceType) * source.size());
您分配了
source.size()
,但您复制了 sizeof(SourceType) * source.size()
。显然比您分配的多 sizeof(SourceType)
倍。我期望这里会出现未定义的行为。因此,您会溢出分配的内存,并且您可能会从未分配的源进行复制。 to.resize(source.size());
memcpy(to.data(), source.data(), source.size());
好吧,这只是问题的一半。您还可以从一种类型复制到另一种类型。我预计这里也会有很多问题。