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

Bri*_*ian 2 c c++ malloc

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

struct ARRAY2D
{
   long[] col;
}

int numRows = 800000;
int numCols = 300;
array = (ARRAY2D*) malloc(numRows * numCols * sizeof(long))
Run Code Online (Sandbox Code Playgroud)

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

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

ken*_*ytm 7

你的版本中会有很多默认值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<int, ARRAY2D> array;
...
// accessing is same as before ...
array[1204].col[212] = 4423;
printf("%d", array[1204].col[115]);
...
// no need to free.
Run Code Online (Sandbox Code Playgroud)

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

std::vector<ARRAY2D> 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.
Run Code Online (Sandbox Code Playgroud)


mlo*_*kot 6

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

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

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

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

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