我正在编写包含这种结构的应用程序:
typedef struct Triangle{
struct Triangle* Neighbor[3];
some other datas...
} Triangle;
每个三角形有3个邻居。请注意,三角形是双重连接的,因为三角形的邻居包含当前三角形作为其邻居。 我的算法将遍历图表,有时会添加一个新的三角形,有时会删除一个。它以1个三角形开头,最后我们将有 N 三角形。
我事先知道 M 是 N 的平均值,我们也知道 N 很少大于 2M < / strong>(可能是5%的时间)
为了给你一个更好的视图,这段代码更新了Triangle的邻居。
void update_triangle_neighbors(Triangle* T, Triangle* oldptr, Triangle* newptr){
if(T->Neighbor[0]==oldptr)
T->Neighbor[0] = newptr;
else if(T->Neighbor[1]==oldptr)
T->Neighbor[1] = newptr;
else
T->Neighbor[2] = newptr;
}
我有两个选择:
1:立即分配一个 2M 三角形数组,如果我们想添加一个新三角形,如果数组已满,则重新分配1.5x之前的大小
要删除我有指针*toRemove
的三角形,我必须:
1.1:我更新了邻居:
for(i=0; i<3; i++)
update_triangle_neighbors(&(toRemove->Neighbor[i]), toRemove, NULL)
1.2:更新要链接到*toRemove
的最后一个三角形的邻居,而不是之前的最后一个三角形
for(i=0; i<3; i++)
update_triangle_neighbors(&(LastTriangle->Neighbor[i]), LastTriangle, toRemove)
*LastTriangle
复制到*toRemove
并减少包含数组大小的变量 2:每次我必须添加或删除三角形时,请使用 malloc 和 free 。
要删除我有指针*toRemove
的三角形,我必须:
free(toRemove)
方法 1 的优点是它只有一个malloc 95%的时间,并且它可以通过仅分配一个大数组来改善空间局部性。缺点是删除有点复杂,如果有太多的三角形,我们将不得不做realloc
。
您认为最好的主意是什么? (这是一个大学项目,我不知道我是否有时间实施这两个项目并做基准测试)
TL; DR:当您几乎知道阵列的大小但不知道必须随机访问时,预先分配的链表或普通链表。
编辑:谢谢大家的好建议!我之后回答了我自己的问题,但我仍然愿意接受建议:)答案 0 :(得分:1)
正如Andrew Henle指出的那样,realloc()
无法正常工作,因为它可能会更改整个数组内存中的位置,并且所有Triangle*
指针都会指向错误的地址。我可以用我的数组中的索引替换Triangle*
指针,但这会使我的所有内容复杂化,特别是对于调试。
因此,我认为我会采用迄今为止最简单的第二种方法。此外,根本没有证据表明第一种方法可以更快。
如果我想在程序运行良好时加快我的程序,我仍然可以实现我自己的malloc&#39;以这种方式(建议hexasoft):
为什么你甚至会想到在这种情况下做一个realloc?
我真的不知道,回想起来真是太愚蠢了。地方在这里并不是那么重要,我准备移山而只是为了获得一点点。
答案 1 :(得分:0)
我只会使用calloc
来分配(它为你的内存零),
并且可以自由地释放...如果你在现代操作系统上运行,那么应该没有多少惩罚...
如果在你的研究中你发现你需要做别的事情,那么在那里查看选项,但我认为无论如何重新分配代码气味,如果你有一个以上的指针,那么使用它真的很糟糕记忆......