好的,伙计们,伙计。
我正在尝试使用C中的列表来模拟基本内存管理(LRU)。我正在使用linux / list.h提供的实现,并且我在列表之前最初构建列表时遇到了困难(例如物理帧) 填上。我将发布我的代码片段(以及输出)并在之后解释:
/* Initialize list */
LIST_HEAD(listInstance);
myFrame** frameInstance;
frameInstance = (myFrame**) malloc(
frameTableSize * sizeof(*frameInstance));
稍后,当我实际检查一个免费插槽时:
/* List operations */
frameInstance[j] = (myFrame*) malloc(
sizeof(frameInstance));
frameInstance[j]->Index1 = lv1IndexNum;
printf("Index1: %d\n", frameInstance[j]->Index1);
printf("j: %d\n", j);
/* Add most recently used frame to the head of the list */
list_add(&frameInstance[j]->list, &listInstance);
j++;
list_for_each(pos, &frameInstance[0]->list) {
tmp = list_entry(pos, myFrame, list);
printf("%d, ", tmp->Index1);
}
printf("\n");
所以,listInstance是我的实际列表,frameInstance是我列表中的一个元素(它包含我真正关心的数据, Index1 ),而j只是一个确保我的计数器不要因我有多少物理帧而填满我的列表(这没有显示)。
这是我上面代码的输出:
第0行:
找到一个免费的框架...
Index1:1
j:0
0,
第1行:
找到一个免费的框架...
Index1:79
j:1
0,79,
第2行:
找到一个免费的框架...
Index1:23
j:2
0,23,79,
这里的问题很明显。第一个要素显然不正确。此外,list_add()不是将frameInstance添加到列表的头部,而是添加到列表的第二个元素。
正如你们中的一些人可能会想的那样,也许只是在头部之后添加一个元素(例如,添加第一个元素,Index1:1,会生成一个0,1的列表),所以我尝试打印在列表后面添加一个额外的尾部,如下:
...
list_for_each(pos, &frameInstance[0]->list) {
tmp = list_entry(pos, myFrame, list);
printf("%d, ", tmp->Index1);
}
tmp = list_entry(pos->next, myFrame, list);
printf("%d, ", tmp->Index1);
这在列表的尾端产生了额外的0。所以,这不是问题。
你们有什么看法我的代码不正确?我可以提供更多代码,虽然这已经是tl;博士......
由于
更新:
所以我发现了一个关于这个列表的相当重要的事实。这个列表,正如我们用头部和尾部可视化的那样,是向后的。例如,在
列表中0,158,15,163,840,117,632,862,
当我用
删除“尾巴”时list_del(&frameInstance[frameTableSize - 1]->list);
我实际上正在移除最近访问过的元素(例如,“head”)。这将产生如下列表:
0,15,163,840,117,632,862,
我希望这会有所帮助。
答案 0 :(得分:0)
解决:
问题在于我和list.h对头尾的解释是相反的。我假设您总是希望O(1)访问头部,因此您最近最少使用的项目将在尾部找到。他们的解释恰恰相反。
最后,我把它全部废弃,因为它正在谋杀我的大脑,并决定实施一个虚拟时间系统,它跟踪每个帧最后被引用的时间。 LRU元素是具有最低虚拟时间(最大间隙)的元素。