首页 > 解决方案 > 在 void 函数中重新分配

问题描述

在我想保留为无效的函数中使用 realloc 时,我遇到了内存泄漏问题。我正在构建的代码用于将稀疏矩阵数据类型从“CSR”转换为称为“CSR-DU”的增量单位格式。

包含 realloc 的违规函数的头文件:

void csr_to_csrdu(..., int *ctl_size, uint64_t **ctl, ...);

ctl 是一个双指针,指向数组数据,当数组通过 realloc 填满时,数组数据将被修改和重塑。数组是动态大小的,在执行之前无法猜测最终大小。因此需要一个指向数组大小的指针和一个双指针来保存 main() 中数据数组的内存地址。

在 main() 中:

ctl = (uint64_t **) malloc( sizeof(uint64_t *) );
ctl_data = (uint64_t *) malloc( *ctl_size * sizeof(uint64_t) );

*ctl= ctl_data; // point to memory data

// call data type conversion
csr_to_csrdu(..., ctl_size, ctl, ...);

// compute sparse matrix-vector multiplication w/ ctl
spmv_csrdu(..., ctl_size, *ctl, ...);

// free ctl data - my problem!
free( ??? );

在函数内部,realloc 看起来像这样(一些伪代码):

if( ctl_index >= *ctl_size )
{
    int estimate  = get_estimate();
    tempPtr = realloc(*ctl, (*ctl_size + estimate)*sizeof(uint64_t) );

    if( tempPtr  == NULL ){ 
      print_fatal_error();
      exit();
    }else{ 
      *ctl = tempPtr;
    }
}

但是,在函数内部发生重新分配后,我似乎无法弄清楚如何释放“ctl_data”。我最初在 main() 中的地址已被销毁。我尝试无济于事的事情:

// both cause "double free or corruption" crash
free( ctl_data );   
free( *ctl );

我不知道如何在这里进行。有什么办法可以让我安全地释放在函数内部创建的“tempPtr”?

标签: c

解决方案


简短的回答:

free(*ctl);
free(ctl);

当您调用 时realloc,它可能会或可能不会释放您最初分配的指针(ctl_data在 中的内容main),这意味着ctl_data可能不再有效释放,因此不应该(并且您不应该尝试访问它最初指向的任何内存至)。事实上,一开始它是相当多余的,至少就可见代码而言。缺少一些你没有展示的其他用途,它会更干净:

ctl = malloc( sizeof(uint64_t *) );
*ctl = malloc( *ctl_size * sizeof(uint64_t) );    

更进一步,使用单个指针和单个分配可能会更简洁:

uint64_t *ctl_data = malloc(*ctl_size * sizeof(uint64_t));
...
csr_to_csrdu(..., ctl_size, &ctl_data, ...);
...
spmv_csrdu(..., ctl_size, ctl_data, ...);
...
free(ctl_data);

推荐阅读