代码应导致分段错误,因为由于list1头部的浅表复制节点被删除,但list2头部仍指向该位置

问题描述 投票:0回答:1

代码应由于浅拷贝而导致分段错误,但当在main()中为list2调用printAll()时,它允许打印list2头节点的地址。应该怎么做才能获得预期的行为?还请解释为什么会这样?我是新手。谢谢。

>>>> when tried with #pragma pack(1) it resuted in the first output

>>>> Without #pragma pack(1) it resulted in the second output



Here is the code i wrote.
The code is for creating an object (list1) of SLL class(singly linked list) and copying it to another object(list2) of SLL class.
#include <iostream>
using namespace std;

//#pragma pack(1)
class Node{
        public:
                char letter;
                Node *next;
};
class SLL{
        private:
                Node *head, *tail;
        public:
                SLL(){
                        head = NULL;
                        tail = NULL;
        }
        void printAll();// for printing the list
        void insertNewNode(char item);// for insertion at head                                
        //function for deletion at head
        void deleteAtHead(){ 
                   Node *tmp;
                   tmp = this->head;
                   this->head = this->head->next;
                   free(tmp);
        }
};
//it is for printing a singly linked list
void SLL::printAll(){

        Node *p;
        p = head;
        cout<<"VALUE  "<<"           "<<"  ADDRESS"<<endl;
        while(p!=NULL){
                cout <<p->letter << "--------------- "<<p<<endl;
                p = p->next;
        }
}
void SLL::insertNewNode(char item){
        Node* temp;
        temp = (Node *)malloc(sizeof(Node));
        temp->letter = item;
        temp->next = head;
        head = temp;
}
int main(){
        SLL list1;
        list1.insertNewNode('D');
        list1.insertNewNode('C');
        list1.insertNewNode('B');
        list1.insertNewNode('A');

        cout<<"PRINTING LIST1"<<endl;
        list1.printAll();
        cout<<""<<endl;

        cout<<"SHALLOW COPY INVOKED"<<endl;
        SLL list2 = list1;
        cout<<""<<endl;

        cout<<"PRINTING LIST2"<<endl;
        list2.printAll();

        list1.deleteAtHead();
        cout<<""<<endl;

        cout<<" LIST1 AFTER ITS HEAD DELETION"<<endl;
        list1.printAll();
        cout<<""<<endl;

        cout<<" LIST2"<<endl;
        list2.printAll();       // as soon as this is executed it should result in runtime error
        return 0;
}


>>>>>>> Output1:
PRINTING LIST1
VALUE               ADDRESS
 A ------------- 0x5578d6f872e0
 B ------------- 0x5578d6f872c0
 C ------------- 0x5578d6f872a0
 D ------------- 0x5578d6f87280

SHALLOW COPY INVOKED

PRINTING LIST2
VALUE               ADDRESS
 A ------------- 0x5578d6f872e0
 B ------------- 0x5578d6f872c0
 C ------------- 0x5578d6f872a0
 D ------------- 0x5578d6f87280

 LIST1 AFTER ITS HEAD DELETION
VALUE               ADDRESS 
 B  ------------- 0x5578d6f872c0
 C  ------------- 0x5578d6f872a0
 D  ------------- 0x5578d6f87280

 LIST2
VALUE               ADDRESS
  --------------- 0x5578d6f872e0

>>>>>> Output2:

PRINTING LIST1
VALUE               ADDRESS
 A ------------- 0x55baac1032e0
 B ------------- 0x55baac1032c0
 C ------------- 0x55baac1032a0
 D ------------- 0x55baac103280

SHALLOW COPY INVOKED

PRINTING LIST2
VALUE               ADDRESS
 A  ------------- 0x55baac1032e0
 B  ------------- 0x55baac1032c0
 C  ------------- 0x55baac1032a0
 D  ------------- 0x55baac103280

 LIST1 AFTER ITS HEAD DELETION
VALUE               ADDRESS
 B  ------------- 0x55baac1032c0
 C  ------------- 0x55baac1032a0
 D  ------------- 0x55baac103280

 LIST2
VALUE               ADDRESS
--------------- 0x55baac1032e0
B--------------- 0x55baac1032c0
C--------------- 0x55baac1032a0
D--------------- 0x55baac103280
c++14 copy-constructor shallow-copy
1个回答
0
投票

指针指向内存的某个区域。内存的任何区域。程序从操作系统获取内存,通常将其分成大块(“页面”),然后由程序运行时对其进行细分。通过malloc,new和delete调用的例程可以执行此操作,还可以使用从子例程调用和返回的机制。

程序通常不返回分配给他们的页面。而是仅重新使用该存储器,例如存储不同的变量。这就是为什么所谓的“悬空指针”如此危险的原因。使用它时,它将返回数据。仅仔细检查将显示该数据没有意义。它甚至可能会长时间返回正确的数据,直到内存区域被回收并被其他内容覆盖。然后您的程序突然显示“未定义的行为” ...

© www.soinside.com 2019 - 2024. All rights reserved.