在我想保持为空的函数中使用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( ??? );
在函数内部,重新分配看起来像这样(一些伪代码):
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”吗?
答案 0 :(得分:2)
简短回答:
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);