访问std::list元素将转储核心
Accessing std::list element gets core dumped
#include <iostream>
#include <string>
#include <fstream>
#include <list>
#include <map>
#include <iomanip>
using namespace std;
void runSimulation(int frameNum, fstream &fs);
void handleMemory(string address);
void handleAddress(int frameNum, string address);
void insertValue(string index);
void replaceValue(string index);
void updateOrder(list<string>::iterator orderPos);
int hit_num = 0, miss_num = 0;
const int INDEX_BITS = 5;
typedef map< string, list<string>::iterator > Memory;
typedef pair< string, list<string>::iterator > MemPair;
Memory memory;
list<string> order;
int main(){
fstream fs;
fs.open("trace.txt", fstream::in);
cout << "LRU---" << endl;
cout << left << setw(10) << "size";
cout << left << setw(15) << "miss";
cout << left << setw(20) << "hit";
cout << "page fault ratio" << endl;
for(int i=256; i<=512; i*=2){
runSimulation(i, fs);
fs.clear();
fs.seekg(0, ios::beg);
}
fs.close();
return 0;
}
void runSimulation(int frameNum, fstream &fs){
memory.clear();
order.clear();
hit_num = 0;
miss_num = 0;
string str;
while(getline(fs, str)){
handleAddress(frameNum, str);
}
cout << left << setw(10) << frameNum;
cout << left << setw(15) << miss_num;
cout << left << setw(20) << hit_num;
cout << fixed << setprecision(9) << (double)miss_num/(miss_num + hit_num) << endl;
}
void handleAddress(int frameNum, string address){
string index;
Memory::iterator found;
index = address.substr(0, INDEX_BITS);
found = memory.find(index);
if(found == memory.end()){ // miss
miss_num++;
if(memory.size() < frameNum){ // there are empty spaces
insertValue(index);
}
else{
replaceValue(index);
}
}
else{ // hit
hit_num++;
//cout << "hit: " << found->first << endl;
updateOrder(found->second);
}
}
void insertValue(string index){
//cout << "insert: " << index << endl;
string *newIndex = new string;
order.push_back(index);
list<string>::iterator it = order.end();
it--;
memory.insert(MemPair(index, it));
}
void replaceValue(string index){
//cout << "replace: " << index << endl;
memory.erase(order.front());
order.pop_front();
insertValue(index);
}
void updateOrder(list<string>::iterator orderPos){
string value = *orderPos;
order.erase(orderPos);
order.push_back(value);
}
我正在尝试模拟操作系统中最近最少使用的机制。但我想,如果你不知道的话,你仍然可以理解这个问题。
输入将是一系列假想的存储器地址,并且它们在整个程序中以string
的形式被操纵。(我说的不是变量的地址或指针之类的。)每一行都包含一个地址,我用getline
逐行读取。
我需要一直维护两个容器
第一个是地图,其类型为<string, list<string::iterator>>
。这记录虚拟存储器中当前是否存在一个地址以及该地址在列表(第二个容器)中的位置
第二个是列表,其类型为list<string>
。这样可以跟踪每个地址的"最近性"。最近的在后面,最近的在前面。
在获得一个地址后,如果该地址在映射中不存在(并且虚内存中仍然存在空格),则它将首先被push_back
写入列表。然后,我会记录该元素在列表中的位置,制作pair<string, list<string::iterator>>
(first
是地址,second
是位置),并将insert
放入映射中。
如果想象中的内存已满,则弹出最近的内存并插入新的内存。两个容器都应进行维护。通过访问列表的前面,我知道哪一个是最近的。
如果映射中已经存在地址(命中),则列表中相应的数据将再次被erase
d和push_back
ed放入列表中,使其成为最新的数据。
问题就在这里
在运行输入时,有时我会得到核心转储。gdb告诉我问题总是在updateOrder
中(我尝试了几种不同的重新排列代码的方法)。我想我没有很好地处理迭代器。
更有趣的是,如果我做runSimulation(64, fs)
,那么frameNum
为64就可以了,核心转储为128。然而,如果我先做runSimulation(128, fs)
,它在128处会很好,但在256处会被丢弃。
runSimulation
开始时的初始化过程中是否出现问题?或者迭代器指向错误的位置?
问题出现在updateOrder
中。您可以擦除现有节点并创建一个新节点,但memory
仍然有一个迭代器用于擦除的节点。您可以使用新位置更新memory
,但更好的解决方案是使用splice
:
void updateOrder(list<string>::iterator orderPos){
order.splice(order.back(), order, orderpos);
}
这将把现有节点移到列表的末尾,而不会使任何现有迭代器无效。
顺便说一句,当您分配一个字符串(您不使用)时,insertValue
中的内存会泄漏。
- 如何找出GDB的SIGTRAP核心转储的根本原因
- C++映射分割错误(核心转储)
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 浮点异常(核心转储)#694457
- 分段错误(核心转储)但无法弄清楚
- 链接到libkcapi时没有核心转储
- 检测到堆栈粉碎:已终止 中止(核心已转储)
- 分段错误(核心转储) - 使用 SavedModel 的 Tensorflow C++ API 进行推断
- 我不知道为什么这段代码会让核心被转储?
- 在基数排序中,我得到 munmap_chunk():无效指针和中止(核心转储).为什么?
- 访问std::list元素将转储核心
- 使用SIGSEGV或SIGABRT信号转储核心并终止进程
- Eclipse (C++) 崩溃 无法写入核心转储.核心转储已被禁用
- 已终止(转储核心)
- 转储核心时拍摄堆快照的时间
- 读取字符串时转储核心
- 当main函数返回时转储核心
- 是否可以转储核心但不退出进程
- 在尝试libssh身份验证时转储核心