有没有办法避免valarray和数组之间的复制?

时间:2011-07-27 16:24:20

标签: c++ arrays valarray

我在列表中有很多数据,比如每个元素中有几个kbytes,我想逐个提取每个数据来进行一些数字处理。这些数据最初存储为float []。由于处理涉及大量的索引和全局计算,我认为valarray可能很容易编程。但是如果我使用valarray,我可能必须首先从数组复制到valarray,然后复制回数组。有什么方法可以避免这种情况吗?有什么方法让我直接在阵列上工作?或者你有更好的方法来解决类似的问题吗?

2 个答案:

答案 0 :(得分:1)

valarray类型没有提供任何方法将现有数组用于其数据存储;它总是为自己制作副本。您可以从一开始就将值直接存储在valarray中,而不是将数据存储在普通数组中。调用v.resize来设置大小,并使用[]运算符为其分配值,或使用&v[0]获取指向第一个值的指针并像使用迭代器一样使用它缓冲区指针 - valarray的元素连续存储在内存中。

答案 1 :(得分:1)

警告:丑陋的黑客

在我的系统(MS Visual Studio)上,valarray类的定义如下:

template<class _Ty>
class valarray
{
    ...
private:
    _Ty *_Myptr;    // current storage reserved for array
    size_t _Mysize; // current length of sequence
    size_t _Myres;  // length of array
};

所以我可以构建我自己的具有相同布局的类(具有良好的置信度):

struct my_valarray_hack
{
    void *_Myptr;
    size_t num_of_elements;
    size_t size_of_buffer;
};

然后创建一个空的valarray并覆盖其内部变量,使其指向您的数据。

void do_stuff(float my_data[], size_t size)
{
    valarray<float> my_valarray;
    my_valarray_hack hack = {my_data, size, size};
    my_valarray_hack cleanup;

    assert(sizeof(my_valarray) == sizeof(hack));

    // Save the contents of the object that we are fiddling with
    memcpy(&cleanup, &my_valarray, sizeof(cleanup));

    // Overwrite the object so it points to our array
    memcpy(&my_valarray, &hack, sizeof(hack));

    // Do calculations
    ...

    // Do cleanup (otherwise, it will crash)
    memcpy(&my_valarray, &cleanup, sizeof(cleanup));
    // Destructor is silently invoked here
}

这是推荐的做事方式;你应该考虑它,只有你没有其他方法来实现你想要的东西(甚至可能不是那样)。它可能失败的可能原因:

  • valarray的布局在另一种编译模式中可能有所不同(模式示例:调试/发布;不同平台;不同版本的标准库)
  • 如果您的计算以任何方式调整valarray的大小,它将尝试重新分配您的缓冲区并崩溃
  • 如果valarray的实现假定其缓冲区具有例如16字节对齐,它可能会崩溃,执行错误的计算或只是工作缓慢(取决于您的平台)
  • (我确信还有更多原因让它不起作用)

无论如何,它被描述为&#34;未定义的行为&#34;根据标准,严格来说,如果您使用此解决方案,可能会发生任何事情。