C/C++中用于多个可变大小数组的数据结构

Data structure in C/C++ for multiple variable size arrays

本文关键字:小数 数组 数据结构 C++ 用于      更新时间:2023-10-16

这就是当前的问题:
我有几个10000的数组。每个阵列的长度可以在2-15个单元之间。可以使用一些非常低成本的计算来计算所有阵列中的所有元素的总长度和阵列的数量。但是,在完成一些相当昂贵的计算之前,每个阵列中的确切数字是未知的。

由于我知道所有数组中所有元素的总长度,所以我只想使用一个新的/malloc为其分配数据,并在该分配中设置指针。在我当前的实现中,我使用memmove在插入某个项后移动数据,并相应地更新所有指针。

有更好的方法吗?

谢谢,

  • Sid

您所说的更好的方式是什么意思还不清楚。如果您正在寻找工作速度更快、能够提供额外内存的东西,那么您可以保留两个数组,一个包含数据,另一个包含所属数组的索引。添加完所有数据后,可以按索引进行排序,然后按数组分割所有数据,最后扫描数组,得到每个数组所属的指针。

关于内存消耗,根据您有多少个数组,以及您的数据有多大,您可以将索引数据压缩到数据的最后一位,如果您用某个数字来限制它的话。这样,您只需要对数字进行排序,当您在每个数组开始的位置扫取指针时,您可以清除顶部的位。

由于我知道所有数组中所有元素的总长度,我只想使用一个新的/malloc为其分配数据,并在该分配中设置指针。

您可以使用一个大矢量。您需要自己手动计算每个子阵列的偏移量。

矢量保证它们的数据存储在连续的内存中,但如果矢量的使用方式可能会使其重新分配,则要小心维护对单个元素的引用或指针。这应该不是问题,因为你没有添加任何超出初始大小的内容。

int main() {    
std::vector<T> vec;
vec.reserve(calc_total_size());
// now you'll need to manually translate the offset of
// a given "array" and then add the offset of the element to that 
T someElem = vec[array_offset + element_offset];
}

是的,有一种更好的方法:

std::vector<std::vector<Item>> array;
array.resize(cheap_calc());
for(int i = 0; i < array.size(); ++i) {
array[i].resize(expensive_calc(i));
for(int j = 0; j < array[i].size(); j++) {
array[i][j] = Item(some_other_calc());
}
}

没有指针,没有混乱,没有大惊小怪。

您是在寻找内存效率、速度效率还是简单性?

您总是可以编写或下载一个死的简单池分配器,然后将其作为分配器传递给适当的数据结构。因为您事先知道总大小,而且不需要调整向量大小或添加新向量,所以这可能比典型的池分配器更简单。只需malloc一个大块中的所有存储,并保留一个指向下一个块的指针。要分配n个字节,请使用T *ret = nextBlock; nextBlock += n; return ret;。如果你的对象很琐碎,不需要销毁,你甚至可以在最后只做一个大的free

这意味着你可以使用任何你想要的数据结构,或者比较和对比不同的数据结构。vector的一个vector?细胞的巨大vector加上偏移的vector?你想出的其他听起来很疯狂但可能奏效的东西?您可以比较它们的可读性、可用性和性能,而不必担心内存分配方面的问题。

(当然,如果你的目标是速度,那么以这种方式打包可能不是最好的答案。你通常可以通过浪费一点空间来改善缓存和/或页面对齐来获得很大的速度。你可以编写一个奇特的分配器,例如,以转置的方式分配向量空间,以提高算法的性能,该算法在应该执行行主和行主的地方执行列主,反之亦然。)a、 但在这一点上,调整算法可能比调整分配器更容易。)