修改2D Array的malloc策略,使malloc成功

我们最近收到一份报告,说我们的应用程序偶尔会无法运行。 我将问题代码跟踪到这个:

struct ARRAY2D { long[] col; } int numRows = 800000; int numCols = 300; array = (ARRAY2D*) malloc(numRows * numCols * sizeof(long)) 

如果用户没有足够大的空闲块,则此800 Mb的分配可能会失败。 改变我分配内存的最佳方法是什么?

请记住,我有大量代码访问此对象,如下所示:array [row] .col [colNum],所以我需要一些需要辅助或主要查找和替换数组访问代码编辑的东西。

您可以分别分配较小的内存块,而不是一个巨大的块。

 long** array = NULL; array = (long**) malloc(numCols * sizeof(long*)); for (int i = 0; i < numCols; i++) array[i] = (long*) malloc(numRows * sizeof(long)); 

通常,每次分配时内存分配都可能失败 。 但是,从统计上讲,由于内存碎片的原因 ,分配单个大块内存比分配N个更小的块更容易失败。 虽然,上面的解决方案也可能会引起问题,因为它有点像双刃剑,因为它可能导致进一步的内存碎片。

换句话说,通常没有完美的答案,解决方案取决于系统和应用程序的细节。

从评论中可以看出C ++库是一种可能性,然后解决方案基于std::vector (即C ++中向量的通用向量 )或使用Boost.MultiArray

你的ARRAY2D会有很多默认值吗? 如果是,则需要稀疏数组。 最小的改变是使用unordered_map (或hash_mapmap ):

 static const int numRows = 800000; static const int numCols = 300; struct ARRAY2D { long col[numCols]; // initialize a column to zero; not necessary. ARRAY2D() { memset(col, 0, sizeof(col)); } }; // no need to malloc std::unordered_map array; ... // accessing is same as before ... array[1204].col[212] = 4423; printf("%d", array[1204].col[115]); ... // no need to free. 

如果行索引始终是连续的但远小于numRows ,则使用std::vector

 std::vector array; ... // resize to the approach value. array.resize(2000); ... // accessing is same as before ... array[1204].col[212] = 4423; printf("%d", array[1204].col[115]); ... // no need to free. 

我写了一个简单的例子,我将如何在大块中分配数组:

 #include  #include  struct ARRAY2D { long *col; char free; }; struct ARRAY2D *ARRAY2D_malloc( int numRows, int numCols ){ struct ARRAY2D *rows = malloc( numRows * sizeof(struct ARRAY2D) ); if( rows ){ for( int i=0,b=numRows; i= 0 ) if(rows[i].free) free(rows[i].col); free(rows); rows=NULL; break; } for( int j=i; j 

b是一步分配的行数。 当没有大块空闲内存时,用一个减少b是一个简单的策略。

您的代码有语法错误:您缺少分号和long[] col; 是无效的C或C ++。

鉴于:

 struct ARRAY2D { long *col; }; ARRAY2D *array; int numRows = 800000; int numCols = 300; array = (ARRAY2D*) malloc(numRows * numCols * sizeof(long)); 

您可能会分配错误的内存量: sizeof(long)应替换为sizeof *arraysizeof(ARRAY2D)

假设您获得了正确的数量,您可以将array索引为: array[i] ,对于i ,范围为[0, numRows*numCols) 。 您没有为任何array[i] col成员分配任何内存,因此您无法索引任何array[i] col 。 因此,根据您发布的分配方案,您对array[row].col[colNum]是错误的。

如果您发布一些有效的真实代码,也许会有所帮助。