我们得到了如下的2D分配:
char** arr;
short i = 0;
arr = malloc(sizeof(char*)*10);
for( ; i<10; i++)
{
arr[i] = malloc(sizeof(char)*100);
}
分配arr[10][100];
然后我们需要像这样释放它:
for(i=0; i<sizeof(arr); i++) free(arr[i]);
free(arr);
所以我想创造一个节省时间,空间和混乱的功能,我有这个:
void pfree(void** data)
{
int i;
for(i=0; i<sizeof(data); i++)
{
free(data[i]);
}
}
该功能是否相关,如果没有其他方式?
答案 0 :(得分:6)
创建这样的函数是完全合理的。特别是如果它:
我可能会写一个malloc_2d()
和free_2d()
:
void free_2d(void **arr, size_t count) {
int i;
if (arr) {
for (i=0; i<count; ++i)
free(arr[i]);
free(arr);
}
}
void** malloc_2d(size_t count, size_t elem_count, size_t elem_size) {
int i;
void **arr = calloc(count, sizeof(void *));
if (arr == NULL)
return NULL;
for (i=0; i<elem_count; ++i) {
arr[i] = calloc(elem_count, elem_size);
if (arr[i] == NULL) {
free_2d(arr, i);
return NULL;
}
}
return arr;
}
或者,常见的机制是将二维阵列编码成一维阵列。所以,假设我们想要一个16x4阵列。
int *arr = malloc(sizeof(int) * 6 * 4);
for (int i=0; i<16; ++i)
for (int j=0; j<4; ++j)
arr[i*4 + j] = compute(i, j);
答案 1 :(得分:3)
首先,您需要了解pointers are not arrays。 sizeof
在两种类型上的运作方式都不相同
当sizeof
的参数是指针时,它只返回指针的大小,即4或8个字节。
当sizeof
的参数是数组名称时,它返回整个数组的大小。例如;对于int a[10]
,sizeof(a)
将返回10 * sizeof(int) = 40
个字节(int
占用4个字节)。
所以,循环
for(i=0; i<sizeof(arr); i++) free(arr[i]);
这并不像你期望的那样工作。您需要将其更改为
for(i=0; i<10; i++) free(arr[i]);
将您的功能更改为
void pfree(void** data, int size)
{
int i;
for(i=0; i<size; i++)
{
free(data[i]);
}
free(data);
}
答案 2 :(得分:1)
数组的大小按其类型进行编码,因此每当您只传递指向其第一个元素的指针时,该信息就会丢失,sizeof
只会产生指针的大小。因此,您无法以编写方式使用签名,您必须提供数组的大小:
void pfree(void** data, size_t count) {
for(size_t i = count; i--;) free(data[i]);
free(data);
}
注意,那行
for(i=0; i<sizeof(arr); i++) free(arr[i]);
free(arr);
分配的内存错误
char** arr;
short i = 0;
arr = malloc(sizeof(char*)*10);
for( ; i<10; i++) {
...
同样,因为sizeof(arr)
只能再次给出指针的大小!
答案 3 :(得分:0)
您可以通过为整个2D阵列分配足够的空间来简化释放。如果elem_count * elem_size是32位系统上的4的倍数或64位系统上的8的倍数,则此方法非常有效。
void pfree(void **arr, size_t count)
{
if (arr)
{
/* arr[0] points to a contiguous array so no need to go through
the whole array */
free(arr[0]);
free(arr);
}
}
void** pmalloc(size_t count, size_t elem_count, size_t elem_size)
{
int i;
void **result = calloc(count, sizeof(void *));
/* Allocate enough space for the entire array */
int arr_size = elem_count * elem_size;
char *arr = calloc(count, arr_size);
if (arr == NULL || result == NULL)
{
/* may get a memory leak */
return NULL;
}
for (i=0; i<count; ++i)
result[i] = &arr[i * arr_size];
return result;
}