已释放calloc内存,C程序仍被Valgrind检测出内存泄漏求助
PCRE正则拆分操作数/运算符的内存泄漏排查
我通过PCRE正则表达式从输入字符串中拆分操作数与运算符,将其作为独立元素存入二维数组。但Valgrind持续提示存在内存泄漏,尽管我已释放所有calloc分配的内存——正则匹配结果从buffer指针复制到raw的分段中,输出后已释放两者。以下是程序代码及Valgrind检测结果,恳请排查泄漏原因:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <pcre.h> int compile_expression(char *raw, char **buffer, int segment_count, int segment_size, char *source, int size, pcre *regex); int main(void) { char input[100] = {0}; int input_size; fgets(input, 99, stdin); input_size = strlen(input); // compile regex char regex[] = "\(.+\)|\d+\.?\d*|[-+*/^]"; const char *errptr; int erroffset; pcre *re = pcre_compile(regex, 0, &errptr, &erroffset, NULL); if (re == NULL) { printf("regex compile error"); return -1; } char *raw = calloc(20, 10); char **buffer = calloc(20, sizeof(char*)); if (raw != NULL && buffer != NULL) { int err; err = compile_expression(raw, buffer, 20, 10, input, input_size, re); // output if (err == 0) { for (int i = 0; i < 20 && buffer[i] != NULL; i++) { printf("[ %s ]", buffer[i]); } printf("\n"); } else return -1; } free(buffer); free(raw); return 0; } int compile_expression(char *raw, char **buffer, int segment_count, int segment_size, char *source, int size, pcre *regex) { int result = 1; int last_offset = 0; char match_buffer[size]; int ovector[30]; for (int i = 0; i < segment_count && result == 1; i++) { result = pcre_exec(regex, NULL, source, size, last_offset, 0, ovector, 30); if (result < 0) break; memset(match_buffer, 0, sizeof(match_buffer)); // clear strncpy(match_buffer, source + ovector[0], ovector[1] - ovector[0]); buffer[i] = raw + segment_size * i; strncpy(buffer[i], match_buffer, segment_size - 1); last_offset = ovector[1]; } if (result != PCRE_ERROR_NOMATCH && result < 0) { return -1; } return 0; }
Valgrind输出:
==28424== 1 + 1 [ 1 ][ + ][ 1 ] ==28424== ==28424== HEAP SUMMARY: ==28424== in use at exit: 122 bytes in 1 blocks ==28424== total heap usage: 5 allocs, 4 frees, 2,530 bytes allocated ==28424== ==28424== 122 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==28424== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==28424== by 0x487D70E: pcre_compile2 (in /usr/lib/x86_64-linux-gnu/libpcre.so.3.13.3) ==28424== by 0x1093A0: main (in /home/canada/VScode-projects/test/test) ==28424== ==28424== LEAK SUMMARY: ==28424== definitely lost: 122 bytes in 1 blocks ==28424== indirectly lost: 0 bytes in 0 blocks ==28424== possibly lost: 0 bytes in 0 blocks ==28424== still reachable: 0 bytes in 0 blocks ==28424== suppressed: 0 bytes in 0 blocks ==28424== ==28424== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
泄漏原因与修复方案
从Valgrind的调用栈可以明确:泄漏的内存是pcre_compile函数分配的正则表达式对象。你只释放了raw和buffer,但没有调用PCRE库提供的pcre_free函数释放编译后的正则对象re。
修复步骤:
- 在
free(raw)之后,添加pcre_free(re);,确保释放PCRE分配的内存。 - 补充异常分支的内存释放:比如当
raw或buffer分配失败时,以及compile_expression调用失败返回时,也要提前调用pcre_free(re),避免泄漏。
修改后的main函数关键部分示例:
free(buffer); free(raw); pcre_free(re); // 新增:释放PCRE编译的正则对象 return 0;
同时,在else return -1;分支补充释放:
} else { pcre_free(re); return -1; }
当raw或buffer分配失败时也要释放:
if (raw != NULL && buffer != NULL) { // ...原有代码 } else { pcre_free(re); }
内容的提问来源于stack exchange,提问作者expoodo
相关产品推荐
相关产品推荐

