【发布时间】:2014-03-24 15:15:44
【问题描述】:
我有一个包装矢量的类:
template <typename T>
class PersistentVector
{
private:
std::vector<T> values;
public:
std::vector<T> & getValues() throw () { return values; }
....
}
实例是:
PersistentVector<double> moments;
我正在尝试将所有双打副本复制到其他人分配的缓冲区中。这是我创建缓冲区的地方:
// invariant: numMoments = 1
double * data_x = new double[numMoments];
这是我将向量的内容复制到缓冲区的尝试:
double theMoment = moments.getValues()[0];
// theMoment = 1.33
std::memcpy(
data_x,
&(moments.getValues().operator[](0)),
numMoments * sizeof(double));
// numMoments = 1
double theReadMoment = data_x[0];
// theReadMoment = 6.9533490643693675e-310
如您所见,我从缓冲区中获取了一个垃圾值。为什么会这样?
工作解决方案
使用std::copy(感谢 WhozCraig)
double theMoment = moments.getValues()[0];
// theMoment = 1.33
std::copy(moments.getValues().begin(), moments.getValues().end(), data_x);
double theReadMoment = data_x[0];
// theReadMoment = 1.33
失败的解决方案
尝试data() 而不是operator[]()
double theMoment = moments.getValues()[0];
// theMoment = 1.33
std::memcpy(
data_x,
moments.getValues().data(),
numMoments * sizeof(double));
// numMoments = 1
double theReadMoment = data_x[0];
// theReadMoment = 6.9533490643693675e-310
仍然对为什么我的原始代码失败感到好奇!
【问题讨论】:
-
std::copy(moments.getValues().begin(), moments.getValues().end(), data_x)?还是我错过了一些明显的东西? (仅供参考,像“invariant: numMoments = 1”这样的东西不令人欣慰的是,看看这是否真的是一个指向 single double 的指针)。 -
尝试将 .operator[](0) 替换为 .data()。
-
@Ben no,它确实not。
-
@Ben 如果不是普通类型,yes(或赋值运算符等)。如果目标不是诸如插入或后推迭代器之类的东西,则分配(通常)是展开的,否则放置通常是最喜欢的优化。
-
@WhozCraig 为什么不让您的 cmets 成为答案?这是一个常见的陷阱,详细说明对许多用户来说肯定是有价值的。顺便说一句,如果 memcpy 以相反的方式执行 - 从标准数组到向量(内存损坏),问题会更大,更难调试。
标签: c++