C语言解析|分隔CSV文件时报corrupted size vs. prev_size及munmap错误
错误原因分析
核心问题是你直接修改了getline动态分配的line指针的原始指向:getline会在堆上申请内存存储行内容,把内存起始地址存入你传入的line指针,同时内部会记录这块内存的元数据(比如分配长度),你后续的getline复用内存、free释放内存都必须基于这个原始起始地址。你在内层遍历字符的循环中直接执行line++偏移了指针,导致原始地址丢失,触发两个报错:
- 出现
corrupted size vs. prev_size报错:每次getline执行时,都会尝试基于你传入的line指针调整内存大小,你传入的偏移后的指针不属于堆分配器记录的合法起始地址,直接破坏了堆的元数据结构,触发内存损坏报错。同时因为第二次循环开始时line已经指向了上一行的末尾,读取的内容完全错误,所以你会看到乱码输出。 - 启用
free(line)出现munmap报错:free只能接收内存分配函数(malloc/realloc等,getline内部使用此类函数分配内存)返回的原始起始地址,偏移后的地址不属于可释放的合法地址,系统在解除内存映射时找不到对应块,触发munmap报错。
修复方案
遍历行内容时使用临时指针,不要修改原始line指针,同时增加数组边界检查避免c_mktsegment溢出:
#include <stdio.h> #include <stdlib.h> int main() { FILE* fp = fopen("customer.tbl", "r"); if (fp == NULL) exit(EXIT_FAILURE); char* line = NULL; size_t len = 0; while ((getline(&line, &len, fp)) != -1) { char c_mktsegment[100] = {}; int mkt_idx = 0; int count=0; // 用临时指针遍历,不修改原line指针 char *p = line; while(*p != '\0'){ if(*p == '|'){ count++; } else if (count==6){ // 边界检查,避免数组溢出 if(mkt_idx < 99) { c_mktsegment[mkt_idx++] = *p; } } else if (count>6){ c_mktsegment[mkt_idx] = '\0'; break; } p++; } printf("%s\n", c_mktsegment); } fclose(fp); if (line) free(line); return 0; }
运行修复后的代码即可正确输出BUILDING、AUTOMOBILE两个目标值。
内容的提问来源于stack exchange,提问作者Ahasanul Haque
相关产品推荐
相关产品推荐

