读取文件触发munmap_chunk(): invalid pointer错误的技术求助
问题现象
执行从argv[1]指定文件读取数字的代码时,触发「munmap_chunk(): invalid pointer Aborted (core dumped)」错误,且仅在文件首行包含两位及以上数字时出现:
- 不会崩溃的文件内容:
9 10 11 12 13 14 15 16 17 18 19
- 会崩溃的文件内容:
10 10 11 12 13 14 15 16 17 18 19 20
代码中的核心问题
给出的代码存在多处内存越界和逻辑错误,直接破坏堆结构引发崩溃:
循环结构错误:
V = new ELEMENT*[number_of_elements];和后续的元素初始化for循环被写在while(getline(...))内部,导致每次读取一行就重新分配指针数组V,旧内存未释放造成泄漏,重复分配操作还会破坏堆结构。vector索引越界:
vector<int> key_values(number_of_elements);创建的容器索引范围是0~number_of_elements-1,但代码中count从1开始,直接访问key_values[count],当count达到number_of_elements时,会越界访问内存,篡改堆中关键数据。指针数组索引越界:
V = new ELEMENT*[number_of_elements];分配的数组索引范围是0~number_of_elements-1,但后续for循环从i=1遍历到i=number_of_elements,访问V[number_of_elements]属于越界操作,进一步破坏堆结构。冗余类型转换:用
stod(line)将字符串转成double后存入int类型的key_values,既没必要还可能引入精度问题,应该直接用stoi(line)。
修复方案
针对上述问题逐一修正:
1. 调整循环结构
将V的分配和元素初始化代码移到while循环外部,确保只执行一次:
// 原while循环内的V分配和for循环移到此处 V = new ELEMENT*[number_of_elements + 1]; // 适配1-based索引,多分配一个元素 for (int i = 1; i <= number_of_elements; i++){ V[i] = new ELEMENT; V[i]->index = i; V[i]->key = key_values[i]; V[i]->pos = 0; }
2. 修正vector索引问题
将key_values的大小改为number_of_elements + 1,适配从1开始的count:
vector<int> key_values(number_of_elements + 1); // 索引范围0~number_of_elements
3. 替换冗余类型转换
把stod(line)改为stoi(line):
key_values[count] = stoi(line);
4. 增加内存泄漏防护
如果Read命令可能被多次执行,需在重新分配pHeap和V前释放旧内存:
if (pHeap != nullptr) { delete pHeap; pHeap = nullptr; } if (V != nullptr) { for (int i = 1; i <= number_of_elements; i++) { delete V[i]; } delete[] V; V = nullptr; } pHeap= new HEAP; // 后续pHeap初始化代码
修复后的完整Read代码片段
//-------------------------- READ------------------------------// if (command == "Read"){ cout << command << endl; ifstream inputFile(argv[1]); if (!inputFile){ cout << "CANNOT READ" << endl; continue; } else{ string line; getline(inputFile, line); number_of_elements = stoi(line); // 释放旧内存(如果存在) if (pHeap != nullptr) { delete pHeap; pHeap = nullptr; } if (V != nullptr) { for (int i = 1; i <= number_of_elements; i++) { delete V[i]; } delete[] V; V = nullptr; } int count = 1; vector<int> key_values(number_of_elements + 1); // 适配1-based索引 pHeap= new HEAP; pHeap->size = 0; pHeap->capacity = number_of_elements; while(getline(inputFile, line)){ if(count == number_of_elements + 1){ break; } else if(line.empty()){ if(count != number_of_elements) continue; else break; } else{ key_values[count] = stoi(line); ++count; } } // 修正while循环的闭合括号 // 移到while循环外部的V分配和初始化 V = new ELEMENT*[number_of_elements + 1]; for (int i = 1; i <= number_of_elements; i++){ V[i] = new ELEMENT; V[i]->index = i; V[i]->key = key_values[i]; V[i]->pos = 0; } } }
内容的提问来源于stack exchange,提问作者cdt123

