手写链表是分段的,我不';我不明白为什么 我正在做一个有趣的事情,制作一个接口,从C++内部运行GnUpTrm,并且由于某些原因,我的链表实现失败了。

手写链表是分段的,我不';我不明白为什么 我正在做一个有趣的事情,制作一个接口,从C++内部运行GnUpTrm,并且由于某些原因,我的链表实现失败了。,c++,class,linked-list,C++,Class,Linked List,以下代码在plots->append(&plot)行失败。在代码中,我发现由于某种原因,析构函数~John() 下面包含的代码是仅在Plot*上运行的精简版本。最初,我将链表作为模板类制作。它作为ll和ll运行良好,但由于某种原因,它作为ll失败 你能帮我找出它失败的原因吗?也许能帮助我理解如何让它发挥作用 提前:谢谢 //B2S #包括 类图{ 字符标题[80]; 公众: Plot(){} }; 类链接{ 绘图*元素; 链接*下一步; 链接*prev; 友人班; }; ll班{ 链接*头; 链

以下代码在
plots->append(&plot)
行失败。在代码中,我发现由于某种原因,析构函数
~John()

下面包含的代码是仅在
Plot*
上运行的精简版本。最初,我将链表作为模板类制作。它作为
ll
ll
运行良好,但由于某种原因,它作为
ll
失败

你能帮我找出它失败的原因吗?也许能帮助我理解如何让它发挥作用

提前:谢谢

//B2S

#包括
类图{
字符标题[80];
公众:
Plot(){}
};
类链接{
绘图*元素;
链接*下一步;
链接*prev;
友人班;
};
ll班{
链接*头;
链接*尾部;
公众:
ll(){
头=尾=新链接();
head->prev=tail->prev=head->next=tail->next=head;
}
~ll(){
while(头!=尾){
tail=tail->prev;
删除尾部->下一步;
}
删除标题;
}
无效附加(绘图*元素){
尾部->元素=元素;
tail->next=新链接();
尾部->下一步->上一步=尾部;
尾部->下一步=尾部;
}
};
约翰班{
ll*地块;
公众:
约翰(){
plots=newll();
}
~John(){
删除绘图;
}
约翰(情节*情节){
约翰();
绘图->追加(绘图);
}
};   
int main(){
图p;
约翰k&p;
}
在这里,可以将头部和尾部指定为指向同一链接对象。由于您从未重新分配它们中的任何一个,这意味着无论何时更改head的任何属性(例如
head.next=foo
),相同的更改都会应用于tail

意思是头和尾总是有相同的元素,前辈和后辈。显然,这不会导致预期的结果。

声明:

 John();
只是建造了一个新的无名约翰,它被创造并立即毁灭。在当前版本的C++中,无法从另一个构造函数或已构造的对象调用构造函数

这意味着调用
k
John
plots
成员从未初始化,因此从
John
构造函数调用
append
时会崩溃

[正如Neil Butterworth评论的那样,如果您实际构建了一个
ll
实例,那么它还有其他问题,这只是最直接的问题。]

  Plot p;
  John k(&p);
改用这个:

  Plot * p = (Plot*) new Plot;
  John k(p);
这段代码被破坏了,因为一旦p超出范围,k对它的引用就会消失。这并不是导致segfault的错误,但一旦您修复了其他错误,它可能会在以后导致segfault


<>你需要删除p。< /p> ,因为你不能调用C++中的类似构造函数。在

John(Plot* plot){
  John();
  plots->append(plot);
}

第一行使用默认构造函数构造一个新的
John
对象,然后丢弃结果。然后它在
绘图
上调用
追加
(因为它没有设置为任何值,所以是垃圾)。将真正的
绘图
初始化代码重构为一个私有方法,然后在执行任何其他操作之前,在两个构造函数中调用此
init
方法。

面对激烈的竞争,您提出了我所见过的最令人费解的链表实现之一。如果您觉得有必要使用这种愚昧的数据结构,为什么不使用std::list呢?谁在投票支持这个问题?为什么呢?上面的内容从来就不是一个完整的、适当的实现,只是一个简单的、突出的、在我正在进行的实现中不起作用的内容。为什么不使用std::list?我只是喜欢练习而不是魔术,就是这样:)对我来说这似乎相当简单。不过,我不知道为什么要对地块使用动态分配;它应该可以作为(非指针)成员变量正常工作,然后您就不必担心分配它了。同样,你也不需要约翰的析构函数;这一切都会自动完成。啊,谢谢!你似乎一针见血。修复了这个问题,它的编译和运行非常漂亮。当然你可以从另一个构造函数调用构造函数:
John(Plot*Plot):John(){plots->append(Plot);}
@alflagan:对于C++03中的同一个对象,你不能。
  Plot * p = (Plot*) new Plot;
  John k(p);
John(Plot* plot){
  John();
  plots->append(plot);
}