C++ 试着自己实现一个双链接列表;调用afficheList()两次,就会得到一个无穷循环?

C++ 试着自己实现一个双链接列表;调用afficheList()两次,就会得到一个无穷循环?,c++,pointers,struct,dynamic-memory-allocation,doubly-linked-list,C++,Pointers,Struct,Dynamic Memory Allocation,Doubly Linked List,你想阅读我的代码并告诉我哪里出了问题(我希望afficheList(列表)打印列表的元素)吗?在我实现的最右边,我写下了我如何理解我的代码,告诉我是否认为我错了,我经常被告知,在你希望计算机做什么和你告诉它做什么之间有区别 我还想知道我是否应该继续“尝试和犯错”。我害怕内存泄漏!因为我使用动态内存分配 到目前为止,看视频和阅读如何制作双链接列表对我没有帮助;他们的暗示似乎太复杂了,我的小脑袋无法理解 #include <iostream> using namespace std;

你想阅读我的代码并告诉我哪里出了问题(我希望afficheList(列表)打印列表的元素)吗?在我实现的最右边,我写下了我如何理解我的代码,告诉我是否认为我错了,我经常被告知,在你希望计算机做什么和你告诉它做什么之间有区别 我还想知道我是否应该继续“尝试和犯错”。我害怕内存泄漏!因为我使用动态内存分配

到目前为止,看视频和阅读如何制作双链接列表对我没有帮助;他们的暗示似乎太复杂了,我的小脑袋无法理解

#include <iostream>

using namespace std;


/* dans ce fichier je tente de creer une structure d'une liste doublement chainé avec quelques methodes de base que j'y associe
tel que creer une liste, la supprimer, cree un element la suppremer, ajouter un element à la liste et afficher la liste.
les commentation aux dessus de chaque implementation sont les eventuels documentation quan dà  ceux sur les côtes ;  ma vision
de l'implemetation : ceux à  quoi je m'attends qu elle fasse !
*/




// je renome structure Element en elt
// ca me set dans la declaration des structures, elle m'eviter de reécrire  " struct Element" et aussis
//ca m'aide personnellement dans la comprehension des structures !
typedef struct Element elt;

//declaration de la structure Element
struct Element{
    int val;
    elt* next;                                          // pointeur vers l'element d'apres
    elt* prev;                                          //  - -    -   -    -    - d'avant
};

//declaration de la structure list
struct List{
    elt* first;                                         //un pointeur vers un elemnt qui
                                                        // qui saure  le premier element de
                                                        // de la liste
};
/**cree un element à partir d'un entier
*@param un entier
*@return un pointeur à un element
**/
elt* creeElement(int nb){
    Element *res= new Element;                           // j'allou  une memoire pouvant contenir un
                                                         // un element, j'y accede avec le pointer res
    res->val = nb;                                       // ds la memoire, ds la partie val j'y met le param nb
    res->next = nullptr;                                 // dans next je met null
    res->prev = nullptr;                                 // dans prev je met null
    return res;                                          // je retourne l'adress pointé par le pointeur *res
}
/* libere la memoire d'un pointeur  passe en param*/
void deleElement(Element *el){
    delete[] el;                                         // soit un pointeur *el,je libère l'addr mémo pointé
}
/**cree une liste
*@param un pointeur à un element
**/


List* creeList(Element *el){
    List *res = new List;
                                                       // vers un element (first)) je pointe cette mémo avec *res
    res->first = el;                                   // je fais pointé first vers l'adresse du pointeur *el
    return res;                                        // je retourne l'addr mémo du pointeur  *res;
}

/** affiche une liste
*@param un pointeur à une list
**/
void afficheList(List *l){

    Element *el = new Element;                        // pointeur *el pointe vers une mémo dispoé à contenir un elememnt
    el = l->first;                                    // je pointe à first par le pointeur *el
    cout << " {"<<el->val<<"} ";                      // j'affiche le champs val de *el
    while (el->next != nullptr){                      // tant que le pointeur *next de l'element actuel n'est pas null;
        el = el->next;                                // l'elemnt next devient l'element actuel ( par le pointeur el )
        cout << " {"<<el->val <<"} ";                 // j'affiche l'element actuel
    }
    cout << " {"<<el->next <<"} ";
    delete el;                                        // je libère le memoire occupé par le pointeur *el;
}
/** ajoute un element sur une liste
*@param un pointeur à un element et un ptr à une liste
*/
void ajouteElement(List *l, Element *el){
    Element *tempo = l->first;
    while (tempo->next != nullptr){
        tempo = tempo->next;
    }
    el->prev = tempo;
    tempo->next = el;
}

//debut d'echecs
void deleteList( List *l){
    Element *actuel=nullptr;
    Element *next=nullptr;
    actuel = l->first;

    //ca me fait une boucle infini :(
    while(actuel->next != nullptr){
        next = actuel->next;
        delete[] actuel;
        actuel = next;

    }

    delete[] next;

}

void pop_back_List(List *l){
    Element *cible;
    cible = l->first;
    while(cible->next != nullptr){
        cible = cible->next;
    }
    delete[] cible;
}



int main()
{
    cout << "Hello List!" << endl;
    Element *el = creeElement(10);
    List *l = creeList(el);
    ajouteElement(l, creeElement(-2));
    ajouteElement(l, creeElement(12));


    cout <<" list :  " ;
    afficheList(l);
    cout <<" list 1:  " ;
    afficheList(l);

    return 0;
}
#包括
使用名称空间std;
/*这是一个非常简单的结构,它是一个双链结构,它是一个基本的联合方法
请给我一份清单,一份供应商清单,一份供应商清单,一份外部供应商清单。
对事件文件的执行情况进行评论;视觉硕士
实施:我参加了所有的活动!
*/
//je雷诺结构元件
//我可以设置结构声明、结构元素声明等
//我可以帮助你理解结构!
typedef结构元素elt;
//结构元素声明
结构元素{
int-val;
elt*next;//pointeur vers l'element d'apres
elt*prev;/---d'avant
};
//结构清单声明
结构列表{
elt*first;//un pointeur vers un ELMNT qui
//第一要素
//德拉利斯特
};
/**作为一方的基本要素
*@参数不完整
*@返回un pointeuráun元素
**/
elt*元素(内部nb){
Element*res=new Element;//j'allou une memoire pouvant contenir un
//联合国部队,j'y加入阿维克勒指针队
res->val=nb;//ds la memoire,ds la partie val j'y遇见了我
res->next=nullptr;//dans next je遇到null
res->prev=nullptr;//dans prev je met null
返回RES;//JE ReTune Laress点
}
/*自由备忘录*/
无效元素(元素*el){
删除[]el;//soit un pointeur*el,je libère l'addr mémo pointé
}
/**李斯特河
*@参数un pointeuráun元素
**/
列表*列表(元素*el){
List*res=新列表;
//元素(第一)第二点
res->first=el;//je fais pointéfirst vers l'ADRESE du pointeur*el
return res;//je retourne l'addr mémo du pointeur*res;
}
/**阿菲什·乌恩·李斯特
*@参数非指针列表
**/
无效附加列表(列表*l){
Element*el=new Element;//pointeur*el pointe表示元素的内容
EL=L->第一;//JE PooTo.1第一点
cout优先;
//我能相信你的话吗(
while(actuel->next!=nullptr){
下一步=行动->下一步;
删除[]actuel;
actuel=下一个;
}
删除[]下一步;
}
无效弹出列表(列表*l){
元素*cible;
cible=l->first;
同时(cible->next!=nullptr){
cible=cible->next;
}
删除【】cible;
}
int main()
{

首先,C++不是java或C语言,ETAL。记住这一点。换句话说,你用这个代码分配一个新的节点,然后立即用下一行泄露这个分配:

Element *el = new Element; // el points to new node
el = l->first; // el points to head sentinal, node from above leaked
然后,您使用
el
沿着链表向下走,最终到达您希望的最后一个节点。一旦发生这种情况,您将打破循环,但随后您将执行以下操作:

delete el; // delete last node in the list
此时,您已经从实际列表中删除了一个节点,在第一行进行的初始分配早已消失(泄漏),现在您已经从列表中删除了一个节点(最后一个节点),但列表中引用该节点的指针仍然保留原始地址(现在已失效;它是一个悬空指针)

再次执行该函数将到达已失效的悬空指针,尝试跟随它,并在过程中调用未定义的行为

有两件事需要纠正。首先,此函数不应该首先修改列表,所以不要让它修改。请进行
const
纠正,并将
list
指针作为
const
传递。其次,根本不要分配或删除此函数中的内存

void afficheList(列表常量*l){
元素常量*el=l->第一;
下一步;

不能使用
new
在动态范围内实例化的单个对象使用
delete
而不是
delete[]
销毁。感谢您花时间纠正我:)
afficheList
现在运行良好:)。如果您可以随意告诉我使用此代码的其他奇怪/错误的事情@WhozCraig
void afficheList(List const *l) {

    Element const *el = l->first;
    cout << " {" << el->val << "} ";
    while (el->next != nullptr) 
    {
        el = el->next;
        cout << " {" << el->val << "} ";
    }
    cout << " {" << el->next << "} ";
}