2D 数组内存分配 (malloc) 返回 NULL
2D Array Memory Allocation (malloc) Returns NULL
我正在尝试使用GCC编译64 位 CPP 代码,但是一旦我将元素大小从46,000 增加到 46,500,多维(即 2D)数组内存分配就会返回NULL
。我的虚拟内存设置为 96GB,硬件使用 32GB RAM 运行 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
}
函数allocate_mem
与getShortestPath
中用于释放结构的代码不一致。如果arr_data
未在其他地方使用,则应删除此全局变量并按以下方式分配间接数组:
ShortestPath **allocate_mem(int n, int m) {
ShortestPath **arr = (ShortestPath **)calloc(n, sizeof(*arr));
if (arr != NULL) {
for (int i = 0; i < n; i++) {
arr[i] = (ShortestPath *)calloc(m, sizeof(ShortestPath));
if (arr[i] == NULL)
break;
}
}
return arr;
}
笔记:
在free
全局指针指向的内存后,将NULL
存储到全局指针中会更安全。- 对于
allocate_mem
来说,检查它是否可以分配所有数组元素并释放分配的任何内容(如果不能),而不是尝试在调用者函数中进行清理会更一致。
下面是一个更一致的版本和调用代码:
ShortestPath **allocate_mem(int n, int m) {
ShortestPath **arr = (ShortestPath **)calloc(n, sizeof(*arr));
if (arr != NULL) {
for (int i = 0; i < n; i++) {
arr[i] = (ShortestPath *)calloc(m, sizeof(ShortestPath));
if (arr[i] == NULL) {
for (j = i; j-- > 0;) {
free(arr[j]);
}
free(arr);
return NULL;
}
}
}
return arr;
}
ShortestPath *getShortestPath(EdgeWeightedDigraph *digraph, int32 source,
int32 dest)
{
// Function is called multiple times so I clear memory
// before reallocation given values pointed by pointers
// are used in other files in my project after run.
free(spAllPairs);
spAllPairs = NULL;
free(arr_data);
arr_data = NULL;
free(spTreesArray);
spTreesArray = NULL;
spAllPairs = allocate_mem(MAX_VERTICES, MAX_VERTICES);
if (spAllPairs == NULL) {
fprintf(stderr, "Failed to allocate space for Shortest Path Pairs!n");
exit(1);
}
spTreesArray = (DijkstraSPTree *)malloc(MAX_VERTICES * sizeof(DijkstraSPTree));
if (spTreesArray == NULL) {
fprintf(stderr, "Failed to allocate space for DijkstraSPTree!n");
exit(1);
}
for (int32 vertexTo = 0; vertexTo < digraph->vertices; ++vertexTo) {
pathTo(&spTreesArray[source], &spAllPairs[source][vertexTo],
vertexTo);
}
return &spAllPairs[source][dest];
}
编辑正如M.M评论的那样,您应该在 C++ 中使用new
和delete
运算符,而不是malloc()
和free()
。(或者除了malloc
,但为什么要打扰malloc
):
ShortestPath **allocate_mem(int n, int m) {
ShortestPath **arr = new ShortestPath *[n];
if (arr != NULL) {
for (int i = 0; i < n; i++) {
arr[i] = new ShortestPath[m];
if (arr[i] == NULL) {
for (j = i; j-- > 0;) {
delete[] arr[j];
}
delete[] arr;
return NULL;
}
}
}
return arr;
}
ShortestPath *getShortestPath(EdgeWeightedDigraph *digraph, int32 source,
int32 dest)
{
// Function is called multiple times so I clear memory
// before reallocation given values pointed by pointers
// are used in other files in my project after run.
delete[] spAllPairs;
spAllPairs = NULL;
delete[] spTreesArray;
spTreesArray = NULL;
spAllPairs = allocate_mem(MAX_VERTICES, MAX_VERTICES);
if (spAllPairs == NULL) {
fprintf(stderr, "Failed to allocate space for Shortest Path Pairs!n");
exit(1);
}
spTreesArray = new DijkstraSPTree *[MAX_VERTICES];
if (spTreesArray == NULL) {
fprintf(stderr, "Failed to allocate space for DijkstraSPTree!n");
exit(1);
}
for (int32 vertexTo = 0; vertexTo < digraph->vertices; ++vertexTo) {
pathTo(&spTreesArray[source], &spAllPairs[source][vertexTo],
vertexTo);
}
return &spAllPairs[source][dest];
}
相关文章:
- 如何在映射中返回null
- 为什么返回 NULL 不会破坏函数?
- fopen 在 gdb 中返回 NULL
- 为什么要从main()返回NULL?
- 为什么TinyXML2的XMLDocument::FirstChild()函数在尝试解析这个有效的XML文件时返回NULL?
- Box2D World.GetBodyList() 返回 NULL,但 World 显然正在更新对象
- boost::p ython:PyErr_Fetch始终返回 NULL 回溯
- 如何在 Visual C++ 中从返回类型为 map 的函数返回 null?
- 如何在C++中返回Null作为引用
- 从模板化函数返回Null对象
- GDALOpen 在 GEOTiff 文件上返回 null
- PyThreadState_GET() 从 PyImport_GetModuleDict() 中返回 NULL
- (位图)LoadImage() 返回 NULL,GetLastError() 返回 0
- 在构造函数处将类对象强制转换为接口始终返回 NULL
- 如何为迭代器返回"null"值?
- 具有 4 个指针的节点的递归插入函数返回 null
- winAPI FindResource 仅在 DLL 中返回 NULL
- 使用 dlopen/dlsym 打开C++共享库 - dlsym 返回 NULL
- SetWindowsHookEx 在挂接到其他线程时返回 NULL
- 尚未归shared_ptr所有的实例的 shared_from_this() 总是返回 null?