代码应由于浅拷贝而导致分段错误,但当在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
指针指向内存的某个区域。内存的任何区域。程序从操作系统获取内存,通常将其分成大块(“页面”),然后由程序运行时对其进行细分。通过malloc,new和delete调用的例程可以执行此操作,还可以使用从子例程调用和返回的机制。
程序通常不返回分配给他们的页面。而是仅重新使用该存储器,例如存储不同的变量。这就是为什么所谓的“悬空指针”如此危险的原因。使用它时,它将返回数据。仅仔细检查将显示该数据没有意义。它甚至可能会长时间返回正确的数据,直到内存区域被回收并被其他内容覆盖。然后您的程序突然显示“未定义的行为” ...