为何该动态内存分配存在泄漏且扩容时内存占用远超预期?
嘿George,咱们来拆解下你的布隆过滤器为啥扩容时内存远超预期还存在泄漏问题——你的代码里有几处关键错误:
一、内存占用远超预期的核心原因
你的内存分配逻辑完全搞错了二级指针的计算方式,直接导致了内存暴增:
- 指针数组分配多乘了COLUMNS:
不管是temp_bf还是扩容后的bloom_filter,它们都是存放行指针的数组,只需要分配「行数 × 指针大小」的空间就行。但你写的temp_bf=malloc(old_size*COLUMNS*sizeof(unsigned char*))和bloom_filter=malloc(new_size*COLUMNS*sizeof(unsigned char*)),多乘了COLUMNS(4397164)。在64位Windows中,指针大小是8字节,光temp_bf的指针数组就分配了1*4397164*8≈33.5MB,加上每行的4MB,正好接近你看到的37.7MB。正确写法应该是temp_bf=malloc(old_size*sizeof(unsigned char*))。 - 每行分配错误放大了尺寸:
你写的temp_bf[i]=malloc(bloom_filter_rows*COLUMNS*sizeof(unsigned char)),用旧行数×列数来分配每行空间,这完全没必要——你只是要复制原过滤器的每行内容,只需要分配COLUMNS字节(和原行大小一致)就够了。
二、内存泄漏的根源
你的代码有两处直接导致泄漏的问题:
- free语句存在语法错误:
看你的释放代码:for(int j=0;j<old_size;j++) free(bloom_filter[j];和for(int j=0;j<old_size;j++) free(temp_bf[j];,两行都少了右括号),正确写法是free(bloom_filter[j]);。这种语法错误会让编译器报错,或者运行时跳过free逻辑,旧内存块无法被释放,直接造成泄漏。 - 冗余分配增加泄漏风险:
你的扩容逻辑里,为temp_bf每行重新malloc再复制内容是冗余的——如果只是临时保存旧数据,直接把temp_bf[i] = bloom_filter[i];(浅拷贝指针)就行,既省内存又避免了malloc/free配对出错的可能。如果必须深拷贝,也要保证每行malloc的大小和原行一致,且后续必须对应free。
修复后的核心代码示例
给你调整了关键部分的代码,你可以参考:
// 修正后的扩容逻辑(浅拷贝版本,更高效) int old_size = bloom_filter_rows; int new_size = old_size + EXPAND_SIZE; unsigned char **temp_bf = malloc(old_size * sizeof(unsigned char*)); // 直接保存旧行的指针,无需重新分配内存 for(int i=0; i<old_size; i++){ temp_bf[i] = bloom_filter[i]; } // 释放旧的指针数组(不要释放每行,因为指针已经转到temp_bf了) free(bloom_filter); // 分配新的指针数组 bloom_filter = malloc(new_size * sizeof(unsigned char*)); // 复制旧内容 for(int i=0; i<old_size; i++){ bloom_filter[i] = temp_bf[i]; } // 初始化新行 for(int i=old_size; i<new_size; i++){ bloom_filter[i] = malloc(COLUMNS * sizeof(unsigned char)); memset(bloom_filter[i], 0, COLUMNS); // 初始化为全0 } // 释放temp_bf的指针数组 free(temp_bf);
如果需要深拷贝(比如旧内存要被复用),则需要调整为:
// 深拷贝版本的temp_bf初始化 for(int i=0; i<old_size; i++){ temp_bf[i] = malloc(COLUMNS * sizeof(unsigned char)); memcpy(temp_bf[i], bloom_filter[i], COLUMNS); } // 释放旧过滤器的每行和指针数组 for(int j=0; j<old_size; j++){ free(bloom_filter[j]); } free(bloom_filter); // 复制回新过滤器并释放temp_bf for(int i=0; i<old_size; i++){ memcpy(bloom_filter[i], temp_bf[i], COLUMNS); free(temp_bf[i]); } free(temp_bf);
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

