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