首页 > 解决方案 > 使用带有 unique_ptr 的 memcpy 到向量

问题描述

我正在写一段代码,我需要将一个指针复制到一个向量或它的某个部分——定义为:

std::unique_ptr<std::vector<unsigned int>> filtered_profile_ptr = 
  std::make_unique<std::vector<unsigned int>>((int)baselength);

指向另一个指向向量的指针 - 定义为:

std::unique_ptr<std::vector<unsigned int>> profile_vector = 
  std::make_unique<std::vector<unsigned int>>(length + filter_size - 1);

我正在使用 memcpy 函数执行此操作 - 如下所示:

memcpy(&(*profile_vector)[0], &(*profileVector)[length - win_size_left], win_size_left * sizeof(unsigned int));
memcpy(&(*profile_vector)[win_size_left], &(*profileVector)[0], length * sizeof(unsigned int));
memcpy(&(*profile_vector)[length + win_size_left], &(*profileVector)[0], win_size_right * sizeof(unsigned int));

我的问题是:以这种方式使用 memcpy 是否会提供一些隐藏的问题,在某些情况下与内存有关,或者可能与缓冲区有关。

PS 代码运行正常,我只关心看不到的问题。

标签: c++

解决方案


首先,几乎没有理由动态分配向量。您可以通过使用自动存储来大大简化程序:

std::vector<unsigned int> filtered_profile(baselength);
std::vector<unsigned int> profile_vector(length + filter_size - 1);

隐藏的问题memcpy是它仅适用于可简单复制的类型 - 对于其他人来说,行为是未定义的。当然,您的副本目前可能是微不足道的(假设我已经正确阅读了您的代码,因为您正在处理向量的内部缓冲区),但是没有必要依赖那个微妙的细节:您可以使用std::copywhich也适用于非平凡的类型。

这个程序应该做你的 memcpy 所做的事情,除非我误读了你的程序。除了这适用于没有智能指针的向量。这更具可读性,至少对我来说:

assert(std::size(profileVector) >= length);
auto srcB = std::begin(profileVector); // begin
auto srcE = srcB + length;             // end
auto srcL = srcE - win_size_left;      // left from end
auto srcR = srcB + win_size_right;     // right from begin


assert(std::size(profile_vector) >= win_size_left + length + win_size_right);
auto dst0 = std::begin(profile_vector);
auto dst1 = dst0 + win_size_left;
auto dst2 = dst1 + length;

std::copy(srcL, srcE, dst0);
std::copy(srcB, srcE, dst1);
std::copy(srcB, srcR, dst2);

PS请注意,命名两个变量profile_vector并且profileVector非常混乱。考虑重命名其中之一。此外,尚不清楚filtered_profile与复制有何关系。


推荐阅读