我正在尝试实现一个链表(我相信这是一个循环链表),但在使用它时,它最终会崩溃。我认为这是因为我使用的遍历指针未正确设置为0,并最终解除引用并显示未定义的行为。
感谢您的帮助。
这是我正在使用的功能:
struct records t_head = 0;
struct records* find_id(Rect a)
{
struct records* tmp;
struct records* prev;
// Add first node
if (t_head == NULL) {
tmp = new records;
tmp->b = a;
tmp->id = trecord_count + 1;
tmp->tally.resize(labelsInfo.size());
tmp->frames = 0;
t_head = tmp;
t_head->next = NULL;
trecord_count++;
}
else {
// Check if there is any node that has delete_flag set first
tmp = t_head;
while (tmp) {
if (delete_flag) {
// Delete here
if (tmp == t_head) {
t_head = tmp->next;
delete (tmp);
trecord_count--;
}
else {
prev->next = tmp->next;
delete (tmp);
trecord_count--;
}
}
prev = tmp;
tmp = tmp->next;
}
tmp = new records;
tmp->b = a;
tmp->id = trecord_count + 1;
tmp->tally.resize(labelsInfo.size());
tmp->frames = 0;
tmp->next = t_head;
t_head = tmp;
trecord_count++;
}
return tmp;
}
结构定义是:
struct records {
int id;
Rect b;
vector<int> tally= {};
int frames=0;
int delete_flag=0;
struct records *next;
};
答案 0 :(得分:0)
以下代码会运行,但它也会显示评论中已提及的缺陷。
tmp
中的指针,以便使用集delete_flag
搜索记录。这在以下版本中已得到纠正。所需的修改标有//< Tobias
。请注意,在linux下使用valgrind可以轻松找到此类错误。 Andon M. Coleman也提到了in his comment。find_id
版本中,实际上没有搜索a
已实施。我在我的版本中实现了这样的搜索。trecord_count
并再次分配相同的ID。因此,您最终会得到具有相同ID的多个记录。 编辑:我在程序中添加了一些日志记录。也许,这可以帮助您了解发生了什么。此外,我滥用frames
作为真实id
。即,没有两个记录具有相同的frames
- 值。记录在括号中,完整列表在方括号中。并且否您没有循环列表。也许,您会得到错误的印象,因为您在前面添加了新记录,因此,您需要使用t_head
的旧值作为新创建记录的next
指针的值。 / p>
该计划的输出是:
g++ -std=c++11 -g -O0 ./test.cc -o a.exe && ./a.exe
Returning { frames=1 id=1 b=1 }
Full content:
[ { frames=1 id=1 b=1 } ]
Adding { frames=2 id=2 b=2 }
Returning { frames=2 id=2 b=2 }
Full content:
[ { frames=2 id=2 b=2 }, { frames=1 id=1 b=1 } ]
Adding { frames=3 id=3 b=3 }
Returning { frames=3 id=3 b=3 }
Full content:
[ { frames=3 id=3 b=3 }, { frames=2 id=2 b=2 }, { frames=1 id=1 b=1 } ]
Deleting head { frames=3 id=3 b=3 }
Adding { frames=4 id=3 b=4 }
Returning { frames=4 id=3 b=4 }
Full content:
[ { frames=4 id=3 b=4 }, { frames=2 id=2 b=2 }, { frames=1 id=1 b=1 } ]
Returning { frames=2 id=2 b=2 }
Full content:
[ { frames=4 id=3 b=4 }, { frames=2 id=2 b=2 }, { frames=1 id=1 b=1 } ]
Deleting { frames=2 id=2 b=2 }
Adding { frames=5 id=3 b=5 }
Returning { frames=5 id=3 b=5 }
Full content:
[ { frames=5 id=3 b=5 }, { frames=4 id=3 b=4 }, { frames=1 id=1 b=1 } ]
At exit: [ { frames=5 id=3 b=5 }, { frames=4 id=3 b=4 }, { frames=1 id=1 b=1 } ]
以下是名为test.cc
的程序:
#include <vector>
#include <iostream>
#include <cstdlib>
typedef int Rect;
struct records {
int id;
Rect b;
std::vector<int> tally= {};
int frames=0;
int delete_flag=0;
struct records *next;
};
struct records *t_head = 0;
int trecord_count = 0;
int trecord_frames = 0;
std::ostream& operator << (std::ostream& os, const records& r) {
os << "{ frames=" << r.frames << " id=" << r.id << " b=" << r.b << " }";
return os;
}
std::ostream& operator << (std::ostream& os, const records* r) {
os << "[ ";
if(r)
os << *r;
for(r=r->next; r; r=r->next)
std::cout << ", " << *r;
std::cout << " ]\n";
}
struct records* find_id(Rect a)
{
struct records* tmp;
struct records* prev;
// Add first node
if (t_head == NULL) {
tmp = new records;
tmp->b = a;
tmp->id = trecord_count + 1;
tmp->tally.resize(0);
tmp->frames = ++trecord_frames;
t_head = tmp;
t_head->next = NULL;
trecord_count++;
}
else {
// Check if there is any node that has delete_flag set first
tmp = t_head;
while (tmp) {
if (tmp->delete_flag) {
// Delete here
if (tmp == t_head) {
std::cout << "Deleting head " << *tmp << std::endl;
t_head = tmp->next;
delete (tmp);
trecord_count--;
tmp = t_head; //< Tobias
}
else {
std::cout << "Deleting " << *tmp << std::endl;
prev->next = tmp->next;
delete (tmp);
trecord_count--;
tmp = prev->next; //< Tobias
}
} else {
prev = tmp;
tmp = tmp->next;
}
}
// Search for the id
tmp = t_head;
while(tmp && (tmp->b != a))
tmp = tmp->next;
if(!tmp) {
tmp = new records;
tmp->b = a;
tmp->id = trecord_count + 1;
tmp->tally.resize(0);
tmp->frames = ++trecord_frames;
tmp->next = t_head;
t_head = tmp;
std::cout << "Adding " << *tmp << std::endl;
trecord_count++;
}
}
std::cout << "Returning " << *tmp << std::endl;
std::cout << "Full content:\n" << t_head << std::endl;
return tmp;
}
int main() {
find_id(1);
find_id(2);
find_id(3);
t_head->delete_flag=1;
find_id(4);
records* r = find_id(2);
r->delete_flag = 1;
find_id(5);
std::cout << "\nAt exit: " << t_head;
return 0;
}
/*
Local Variables:
compile-command: "g++ -std=c++11 -g -O0 ./test.cc -o a.exe && ./a.exe"
End:
*/