代码应该导致分段错误,因为由于 list1 头部的浅拷贝节点被删除但 list2 头部仍然指向那里

Code should result in segmentation fault because due to shallow copy node at head of list1 gets deleted but list2 head still points there

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

>>>> 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

指针指向某个内存区域。任何内存区域。 程序从操作系统获取内存,操作系统通常以大块 ('Pages') 的形式提供内存,然后程序运行时将其细分。由 malloc、new 和 free、delete 调用的例程执行此操作,还有从子例程调用和 return 的机制。

尝试使用内存中尚未分配给程序的位置会导致分段错误。但是使用分配给程序的内存不会导致错误。

程序通常不会返回分配给它们的页面。相反,内存只是被重新使用,例如存储不同的变量。这是一个优化,因为 OS 分配内存需要花费很多精力。它还减少了程序使用的缓存量。

这就是所谓的'dangling pointer'如此危险的原因。当你使用它时,它是 returns 数据。只有仔细检查才会发现数据毫无意义。它甚至可能 return 长时间纠正数据,直到内存区域被回收并被其他东西覆盖。然后你的程序突然显示'undefined behaviour'...