【发布时间】:2017-07-08 08:35:00
【问题描述】:
我正在尝试使用 GCC 编译 64 位 CPP 代码,但是一旦我增加元素大小,多维(即 2D)数组内存分配将返回 NULL从 46,000 到 46,500。我的虚拟内存设置为 96GB,硬件使用 32GB 内存运行 64 位操作系统。 只要 MAX_VERTICES 不超过 46000,代码就可以正常工作。
以下是我试图动态分配的内容:
struct ShortestPath {
real32 totalWeight;
// NOTE: ShortestPath is a list of pointers; does not make copies
// (i.e. side-effects) the pointers point to memory allocated
// in the DijkstraSPTree array in the vehicle_searching module
List<DirectedEdge *> *edgeList;
};
#define MAX_VERTICES 46500
global_variable ShortestPath spAllPairs[MAX_VERTICES][MAX_VERTICES];
在堆上分配内存来替换
spAllPairs[MAX_VERTICES][MAX_VERTICES]
使用以下代码
global_variable ShortestPath **spAllPairs;
global_variable ShortestPath *arr_data;
ShortestPath *getShortestPath(EdgeWeightedDigraph *digraph, int32 source,
int32 dest)
{
free(spAllPairs); // Function is called multiple times so I clear memory
free(arr_data); // before reallocation given values pointed by pointers
free(spTreesArray); // are used in other files in my project after run.
inline allocate_mem(ShortestPath*** arr, ShortestPath** arr_data, int n, int m);
allocate_mem(&spAllPairs, &arr_data, MAX_VERTICES, MAX_VERTICES);
for (unsigned int k = 0 ; k < MAX_VERTICES ; k++) {
if (spAllPairs[k] == NULL) {
while (k >= 1) {
free(spAllPairs[k]);
--k;
}
free(spAllPairs[0]);
free(spAllPairs);
fprintf(stderr, "Failed to allocate space for Shortest Path Pairs!\n");
exit(1);
}
}
spTreesArray = (DijkstraSPTree *)malloc(MAX_VERTICES * sizeof(DijkstraSPTree));
for (int32 vertexTo = 0; vertexTo < digraph->vertices; ++vertexTo) {
pathTo(&spTreesArray[source], &spAllPairs[source][vertexTo],
vertexTo);
}
return &spAllPairs[source][dest];
}
void pathTo(DijkstraSPTree *spTree, ShortestPath *shortestPath, int32 dest)
{
List<DirectedEdge *>::traverseList(freeDirectedEdge, shortestPath->edgeList);
List<DirectedEdge *>::emptyList(&shortestPath->edgeList);
shortestPath->totalWeight = spTree->distTo[dest];
}
int allocate_mem(ShortestPath ***arr, ShortestPath **arr_data, int n, int m)
{
*arr = (ShortestPath **)malloc(n * sizeof(ShortestPath*));
*arr_data = (ShortestPath *)malloc(n * m * sizeof(ShortestPath));
for (int i = 0; i < n; i++)
(*arr)[i] = *arr_data + i * m;
return 0; //free point
}
【问题讨论】:
-
记住堆上的分配必须是连续的。您尝试将 32 gigs 的内存(如果
sizeof(ShortestPath) == 16最有可能是)分配为一大块。如果没有这么大的连续内存块,分配将失败。 -
46000 x 46000低于 1.97 Gigs,而46500 x 46500低于 2.013 Gigs。如果你的结构的大小是 16,那么46000可能会保持在 32 GB 以下,而 46500 会产生超过 32 GB。检查你的mallocs的结果,他们应该在某个时候得到 NULL -
@StephanLechner 物理内存无关紧要,因为我使用的是 malloc,而虚拟内存为 96GB。我不确定它是否是连续的。在“spAllPairs”初始化期间,我在 46500x46500 处得到 NULL。
-
@Someprogrammerdude 是的,ShortestPath 的大小 = 16,如您所指。在这种情况下我该怎么办?重新启动我的电脑或增加虚拟内存的大小有帮助吗?谢谢
-
"我的虚拟内存设置为 96GB,硬件运行 64 位操作系统,使用 32GB 内存" 你喜欢颠簸吗?这就是你如何得到鞭打。
标签: c++ arrays memory-management malloc