我有一个结构Foo;
typedef struct {
int bar;
char baz;
} Foo;
假设我然后将Foo数组声明为;
Foo* arr = new Foo[300];
然后继续用循环初始化每个成员。我非常希望得到所有成员的数组吧;
int* barr_arr = ...
最有效的方法是什么?有没有办法利用内存布局,这样我就不需要遍历整个Foo数组?
既然我们事先知道了内存布局,我们可以利用这样一个事实:如果我们知道对齐的话,我们知道每个成员的地址吗?
答案 0 :(得分:2)
最有效的方法是什么?有没有办法利用内存布局,这样我就不需要遍历整个Foo数组?
我不认为没有循环就可以做到这一点。您可以使用std::transform
来简化代码,但std::transform
会循环。
另外,我建议使用std::vector
而不是使用new
分配数组。
std::vector<Foo> arr(300);
....
std::vector<int> bArr(arr.size());
std::transform(arr.begin(), arr.end(), bArr.begin(), [] -> (Foo const& f) { return f.bar; });
答案 1 :(得分:2)
初始化第一个数组时,可以获取指向每个元素内部字段的指针,并将其存储在单独的数组中。
struct Foo
{
int bar;
float baz;
};
const int SIZE = 5;
Foo foos[SIZE];
int *bars[SIZE];
for(int c = 0; c < SIZE; c++) {
foos[c].bar = c;
foos[c].baz = c;
bars[c] = &foos[c].bar; // Grab pointer to field
}
for(int c = 0; c < SIZE; c++) {
std::cout << "Bar Value: " << *bars[c] << std::endl;
}
答案 2 :(得分:1)
如果Foo
通常存在于数组中,并且经常需要访问bar
和baz
的相应数组,我建议您重新设计数据结构以更好地适应您的问题。显然,我们并没有阅读启发这个问题的代码,但鉴于所提供的信息,我可能会提出类似的建议:
struct FooArray {
int* bars;
char* bazes;
size_t n_elements;
};
这消除了为bar
数组分配新缓冲区的需要,这取决于正在处理的Foo
个数,可能会节省大量内存。
我还要注意的是,如果您不是在低级别工作而且实际上不需要int*
但可以使用std::vector<int>
,那么@R Sahu& #39;答案可能是一个更合适的解决方案。
答案 3 :(得分:1)
目标推动了设计。
如果您的主要用途是连续传递所有bar
成员,baz
成员相同,则创建单独的容器:
std::vector<int> bar;
std::vector<char> baz;
然后将bar
作为数组传递很简单:只需使用bar.data()
。
答案 4 :(得分:1)
如果向Foo
添加一个构造函数,该构造函数的大小与数组相同,则只能有一个Foo
对象。然后,您可以使用下标来访问整个矢量数据或单个元素:
#include <iostream>
#include <vector>
#include <memory>
struct Foo
{
std::vector<int> bars;
std::vector<char> bazs;
std::size_t size;
Foo(size_t size, int bar = 0, char baz = 0) :
bars(size, bar), bazs(size, baz), size{size}
{
}
auto operator[](size_t n)
{
// if (n >= size) ...
struct
{
int &bar;
char &baz;
} temp{ bars[n], bazs[n] };
return temp;
}
};
int main()
{
Foo arr(30, 100, 'a'); // 30 items
std::cout << arr[29].bar << std::endl;
std::cout << arr[29].baz << std::endl;
std::cout << arr.bars[29] << std::endl;
std::cout << arr.bazs[29] << std::endl;
std::unique_ptr<Foo> arr2 = std::make_unique<Foo>(25, 10, 'b'); // 25 items
std::cout << arr2->operator[](15).bar << std::endl;
std::cout << arr2->operator[](15).baz << std::endl;
arr2->bars[15] = 11;
std::cout << arr2->bars[15] << std::endl;
arr2->bazs[15] = 'c';
std::cout << arr2->bazs[15] << std::endl;
return 0;
}
100
a
100
a
10
b
11
c