C ++中的双链表

时间:2009-12-11 05:08:08

标签: c++ pointers linked-list

我有一项任务要求我们实现双向链接列表类。出于某种原因,他们将节点struct定义如下:

struct node {
  node   *next;
  node   *prev;
  T      *o;
};

在我看来,如果结构成员'data'不是指针,那么编写类会容易得多。不用说我无法改变它所以我将不得不解决它。我尝试实现将元素添加到列表开头的方法,如下所示:

template <typename T>
void Dlist<T>::insertFront(T *o) {
    node *np = new node;
    T val = *o;

    np->o = &val;
    np->prev = NULL;
    np->next = first;

    if (!isEmpty()) {
        first->prev = np;
    } else {
        last = np;
    }
    first = np;
}

使用ddd进行调试时我意识到第一次插入数字时一切正常但是第二次绕过一切都搞砸了,因为只要你将'val'设置为新元素就会“覆盖”第一个因为使用了val的内存地址。我尝试做其他事情,而不仅仅是让'val'变量执行以下操作:

T *valp = new T;
T val;
valp = &val;
val = *o;

np->o = valp

这似乎也不起作用。我认为这是因为它只是一个更复杂的形式,我上面做的只是额外的内存泄漏:)

任何正确方向的想法/指针都会很棒。

5 个答案:

答案 0 :(得分:6)

您创建的T val是一个自动变量。你的错误是将地址存储到该堆栈变量。

您应该使用new在堆上分配空间,正如您所怀疑的那样,但您的数据指针需要直接指向new返回的地址。

你最近的尝试中的错误就在这里:

valp = &val;

当您尝试复制val的数据而不是其地址时,您正在将valp更改为指向其他地方(val的地址)。

传递给您的函数的数据应该复制到valp点的新内存中。

答案 1 :(得分:4)

我认为你不应该这样做:

T val = *o;

由于节点结构中的o成员是指针,而insertFront的参数也是指针,因此您的教师可能会打算让您获取指定的指针并存储它在列表中,不要复制对象并存储指向该对象的指针。只需将传递到o的{​​{1}}指针存储为节点的insertFront成员,就可以了。

答案 2 :(得分:0)

 T val = *o;

    np->o = &val;

这部分是可疑的。提示是,一旦函数超出范围,函数中堆栈上分配的内存将不可用。

答案 3 :(得分:0)

您的代码不符合node的定义 - node您定义的是data成员,但在您的代码中,您使用的是o代替。

无论如何,你将不得不做两个动态分配来添加每个节点 - 一个用于节点本身,一个用于它将指向的数据对象。分配该数据对象时,您也可以将new的返回值直接分配给节点中的指针。然后,您需要将指针传递到您刚刚分配的数据对象的数据对象复制到节点中的指针指向的位置。

答案 4 :(得分:0)

认为指针有效负载不方便。但也许该列表用于在现有对象之上创建链接,例如:

struct A { int i; };
A as[10] = { 1,2,3,4,5,6,7,8,9,10 };

LinkedList primes_in_my_data;
insertFront( primes_in_my_data, &as[1] );
insertFront( primes_in_my_data, &as[2] );
insertFront( primes_in_my_data, &as[3] );
insertFront( primes_in_my_data, &as[5] );
insertFront( primes_in_my_data, &as[7] );

// now I have a linked list of primes, and caused no extra memory allocation
// (except for the list overhead)