source: abuse/trunk/src/imlib/linked.cpp @ 535

Last change on this file since 535 was 535, checked in by Sam Hocevar, 11 years ago

imlib: fix an old bug in the linked list that used to cause a memory
leak because not all elements were destroyed, but now simply crashes.

File size: 2.0 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5 *
6 *  This software was released into the Public Domain. As with most public
7 *  domain software, no warranty is made or implied by Crack dot Com or
8 *  Jonathan Clark.
9 */
10
11#include "config.h"
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16
17#include "linked.h"
18
19linked_list::linked_list()
20  : m_first(NULL),
21    m_count(0)
22{
23    ;
24}
25
26//
27// Clear all the nodes in a linked list and dispose of the
28// memory for each one by calling its destructor
29//
30linked_list::~linked_list()
31{
32    m_count = 0; // ensure destructors calling unlink() won't mess with us
33
34    if (m_first)
35        m_first->Prev()->SetNext(NULL); // set the prev nodes next to NULL
36                                        // so we can go until we hit NULL
37    while (m_first != NULL)
38    {
39        linked_node *tmp = m_first->Next();
40        delete m_first;
41        m_first = tmp;
42    }
43}
44
45//
46// Take a node out of the linked list, but do not dispose of the memory
47//
48int linked_list::unlink(linked_node *p)
49{
50    if (!m_count)
51        return 0;
52
53    linked_node *q = m_first;
54
55    while (q != p) // find the node in the list
56    {
57        q = q->Next();
58        if (q == m_first)
59            return 0; // not in the list!
60    }
61
62    q->Prev()->SetNext(q->Next());
63    q->Next()->SetPrev(q->Prev());
64
65    if (p == m_first) // if they want to unlink the first node
66        m_first = (m_first->Next() == m_first) ? NULL : p->Next();
67
68    m_count--;
69    return 1;
70}
71
72//
73// Add a node to the end of a linked_list
74//
75void linked_list::add_end(class linked_node *p)
76{
77    if (m_first)
78        p->SetPrev(m_first->Prev());
79    else
80        m_first = p;
81    p->SetNext(m_first);
82
83    if (m_first != p)
84        m_first->Prev()->SetNext(p);
85    m_first->SetPrev(p);
86
87    m_count++;
88}
89
90// Add a node at the front of the list: just add it at the end and set
91// the first pointer to it
92void linked_list::add_front(class linked_node *p)
93{
94    add_end(p);
95    m_first = p;
96}
97
Note: See TracBrowser for help on using the repository browser.