我正在调试C程序。需要具有3维的巨大数据阵列。我开发了两个用于内存分配/免费的功能。
mm()
用于分配,引用一个记录每个维度大小的数组(您可以在main()
中看到它)。 ff()
用于释放内存。
我在执行fr()
后使用top命令测试了我的代码。它显示内存未释放。
有人能说清楚吗?
提前致谢!
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28338 fsdiag 25 0 165m 164m 1208 R 63.2 26.0 0:00.33 a.out
3439 root 15 0 31740 1180 21m S 1.9 0.2 10:56.47 X
int main(){
unsigned char ***arr;
int dim_len[4]={8832,256,64,0}; // for 3-D array, 0 is mark of tail
unsigned char *p;
mm( &p, dim_len, 0); arr = (unsigned char ***)p;
ff( (unsigned char **)&arr, dim_len);
while(1){}
return 0;
}
void mm( unsigned char **a,
int dim_len[], //dimension size array guarded by 0 in the tail
unsigned char data){ //preset data
if( *dim_len ){
int i;
switch(*(dim_len+1)){
case 0://when allocate memory for unsigned char
*a = malloc( sizeof(unsigned char) * (*dim_len));
break;
default://when allocate memory for pointers
*a = malloc( sizeof(unsigned char *) * (*dim_len));
for( i=0; i<(*dim_len); i++){
mm( (unsigned char **)&((*a)[i*4]), dim_len+1, data);
}
break;
}//end of switch
}//end of if
return;
}
void ff( unsigned char **a,
int dim_len[]){//dimension size array guarded by 0 in the tail
if( *dim_len ){
int i;
switch(*(dim_len+1)){
case 0://when free memory for unsigned char
free( *a);
break;
default://when free memory for pointers
for( i=0; i<(*dim_len); i++){
ff( (unsigned char **)&((*a)[i*4]), dim_len+1); //pointer needs 4 bytes storage
}
free( *a );
break;
}//end of switch
}//end of if
*a = NULL;
return;
}
答案 0 :(得分:3)
你应该只使用dim_len
中数字乘积的大小来计算一块内存。
您分配的数据是碎片化的,并且应该比它应该更大,我很难想象您的代码有任何好处的任何情况。
答案 1 :(得分:0)
将多维数组定义为数组数组的数组是
非常方便,因为你可以用熟悉的元素访问元素
p[i][j][k]
符号,而不是索引算术。但是,其他人
已经指出它的效率低于分配
整个阵列作为一大块。
你可以通过以下技巧获得两全其美:分配
指向dim_len[0]
数组的dim_len[0]*dim_len[1]
指针数组
指向dim_len[0]*dim_len[1]*dim_len[2]
个数据单元数组的指针。
这样,您只有三个分配(与维度一样多)
仍然可以使用简单的p[i][j][k]
表示法,前提是中级
指针数组已正确初始化。你也可以做索引
**p
上的算术,按您的选择。
以下是我使用该技巧的程序版本:
/*
* Allocation of multidimensional arrays.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
/*
* Allocate a multidimensional array of unsigned chars.
* Cast the returned pointer to (unsigned char **...*)
*/
void *mm(const int dim_len[])
{
int i, j, size, nmemb = 1, prev_nmemb;
void *p = NULL, *q = NULL;
void **prev_q;
for (i = 0; dim_len[i]; i++) {
prev_nmemb = nmemb;
nmemb *= dim_len[i];
size = dim_len[i+1] ? sizeof(void *) : sizeof(unsigned char);
prev_q = q;
q = malloc(nmemb * size);
if (i == 0) p = q;
else for (j = 0; j < prev_nmemb; j++)
prev_q[j] = q + j * dim_len[i] * size;
}
return p;
}
/* Free the multidimensional array */
void ff(void *p, int dimensions)
{
int i;
void **q;
for (i = 0; i < dimensions; i++) {
q = *((void **) p);
free(p);
p = q;
}
}
int main(void)
{
const int dims[4] = {8832, 256, 64, 0};
unsigned char ***p;
int i, j, k;
printf("Allocating memory.\n");
p = mm(dims);
printf("Filling the array.\n");
for (i = 0; i < dims[0]; i++)
for (j = 0; j < dims[1]; j++)
for (k = 0; k < dims[2]; k++)
p[i][j][k] = (i + 3*j + 5*k) % 256;
printf("Checking contents.\n");
for (i = 0; i < dims[0]; i++)
for (j = 0; j < dims[1]; j++)
for (k = 0; k < dims[2]; k++)
assert(p[i][j][k] == (i + 3*j + 5*k) % 256);
printf("Waiting 10 seconds.\n");
sleep(10);
printf("Freeing memory.\n");
ff(p, 3);
printf("Waiting 10 seconds.\n");
sleep(10);
return 0;
}
我在这里的测试显示,当我释放多维数组时,内存
实际上是返回操作系统。以下是ps
的输出
刚刚解放后:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
edgar 5201 73.0 3.7 151852 150556 pts/0 S+ 14:11 0:00 ./test
edgar 5201 6.1 0.0 1668 408 pts/0 S+ 14:11 0:00 ./test