是否可以创建无指针功能?

时间:2014-06-01 14:24:26

标签: c function memory-management free

我们得到了如下的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]);
    }
}

该功能是否相关,如果没有其他方式?

4 个答案:

答案 0 :(得分:6)

创建这样的函数是完全合理的。特别是如果它:

  1. 提高代码的清晰度
  2. 降低错误的可能性
  3. 我可能会写一个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 arrayssizeof在两种类型上的运作方式都不相同 当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;
}