我正在尝试在 C 中创建一个通用函数,该函数采用 ANY 类型的二维数组并将其复制到一个连续的内存块中。(我需要这个函数来对我的复杂数据类型进行 MPI 上的聚合操作)。
想象一下我有以下整数数组
int n = 5;
int m = 6;
int** int_array = (int**) malloc(n* sizeof(int*));
for (int i = 0; i < n; i++ )
int_array[i] = (int *) malloc(m * sizeof(int) );
在这种类型的内存分配中,原则上不能希望使用以下指针算法访问 int_array 的第 i,j 个条目
int value = (*lcc)[i*m+j];
因此,我实现了一个函数,该函数基本上分配了一个新的内存块并整齐地排列 int_array 的条目,以便上述索引应该起作用。
void linearize(char*** array, int n, int m,unsigned int size_bytes){
char* newarray = (char*)malloc(m*n*size_bytes);
//copy array!
for (int i = 0;i<n;i++)
for(int j = 0;j<m*size_bytes;j++)
{
newarray[i*m*size_bytes+j] = (*array)[i][j];
}
//swap pointers and free old memory!
for (int i = 0;i<n;i++)
{
char * temp = (*array)[i];
(*array)[i] = newarray + i*m*size_bytes ;
free(temp);
}
}
我想让上述函数适用于任何类型的数组类型,因此我使用 char 指针逐字节地执行操作。我测试了这个函数,到目前为止它可以工作,但我不确定内存释放。
free(temp) 是否释放 int_array[i] 指向的整个内存,即从 int_array[i] 可访问的 m*sizeof(int) 个字节或仅前 m 个字节(因为它认为我们的数组是 char 类型而不是)?或者简单地说,“线性化函数会导致内存泄漏吗?”
先感谢您!
*编辑*
正如 Nicolas Barbey 所建议的,我运行了 valgrind 检查内存泄漏,但没有发现。
因此,总结一下我发现难以理解的关于程序行为的要点是:
在函数 linearize 中,以下代码是否会导致内存泄漏:
char * temp = (*array)[i];
(*array)[i] = newarray + i*m*size_bytes ;
free(temp);
不!!不知何故,gnu编译器足够聪明,可以知道“temp”指向多少字节要释放。最初我担心如果我array[i] 是一个 int 类型的指针,例如,它指向一个内存位置,比如 5 ints = 5*4 字节,那么 free(temp) 只会释放前五个该内存的字节数。
另一点是:如何释放已经线性化的数组?也就是说,如果你有:
// first initialize the array.
int** array = (int**)malloc(5*sizeof(int*);
for(int i = 0; i< 5;i++)
array[i] = ( int* ) malloc(5*sizeof(int));
//now a call to linearize
linearize(&array,5,5,sizeof(int));
... do some work with array ....
// now time to free array
free(array[0]);
free(array);
//suffices to free all memory pointed to by array[i] and as well as the memory allocated
// for the pointers.
感谢讨论和建议。