C++14 代码应该导致分段错误,因为列表1头部的浅拷贝节点被删除,但列表2头部仍然指向那个里
由于浅拷贝,该代码应该会导致分段错误,但相反,当main()中的list2调用printAll()时,它允许打印list2的头节点的地址。应该怎么做才能获得预期的行为?还请解释为什么会发生这种情况?我是初学者,先谢谢你C++14 代码应该导致分段错误,因为列表1头部的浅拷贝节点被删除,但列表2头部仍然指向那个里,c++14,copy-constructor,shallow-copy,C++14,Copy Constructor,Shallow Copy,由于浅拷贝,该代码应该会导致分段错误,但相反,当main()中的list2调用printAll()时,它允许打印list2的头节点的地址。应该怎么做才能获得预期的行为?还请解释为什么会发生这种情况?我是初学者,先谢谢你 >>>> when tried with #pragma pack(1) it resuted in the first output >>>> Without #pragma pack(1) it resulted in the
>>>> 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
>当使用#pragma pack(1)进行尝试时,它会在第一次输出中恢复
>>>>如果没有#pragma pack(1),则会产生第二个输出
这是我写的代码。
代码用于创建SLL类(单链表)的对象(list1)并将其复制到SLL类的另一个对象(list2)。
#包括
使用名称空间std;
//#布拉格语包(1)
类节点{
公众:
字符字母;
节点*下一步;
};
类SLL{
私人:
节点*头,*尾;
公众:
SLL(){
head=NULL;
tail=NULL;
}
void printAll();//用于打印列表
void insertNewNode(char项);//用于在头部插入
//用于在头部删除的功能
void deleteAthad(){
节点*tmp;
tmp=此->头部;
本->头=本->头->下一步;
免费(tmp);
}
};
//它用于打印单链表
void SLL::printAll(){
节点*p;
p=水头;
指针指向内存的某个区域。任何内存区域。
程序从操作系统获取内存,操作系统通常将内存分成大块(“页面”),然后程序运行时将其细分。malloc调用的例程new和free、delete都会这样做,但调用和返回子程序的机制也会这样做
试图使用内存中未分配给程序的位置会导致分段错误。但使用分配给程序的内存不会导致错误
程序通常不会返回分配给它们的页面。相反,内存只是重复使用,例如存储不同的变量。这是一种优化,因为操作系统分配内存需要花费大量精力。它还减少了程序使用的缓存量
这就是所谓的“悬空指针”如此危险的原因。当你使用它时,它会返回数据。只有仔细检查才会发现数据毫无意义。它甚至可能在很长一段时间内返回正确的数据,直到内存区域被回收并被其他内容覆盖。然后你的程序突然显示“未定义的行为”…C++14 h作为智能指针。使用它们。它还有内置的列表。也可以使用它们。@EvertW作为学习过程的一部分,我正在尽可能多地探索,因此我尝试了它。你正在教自己重新发明轮子。你应该尽可能好地使用语言,制作一个对你有用/有趣的程序。智能指针和列表,在标准模板库中发现的哈希映射等使低级内存管理过时。在现代C++中,你几乎不应该直接使用新的、删除和指针算法。@ C++中的EvertW总是面临低层次的实现细节。(到写一个正确的链表所需的程度),你将无法得到任何地方。请不要劝阻人们学习那些肮脏的基础。换句话说,不要在C++中使用<代码> MalcC 和<代码>免费< /代码>(警告适用)。,它们不会调用正确的构造函数和析构函数。在学习时使用new
和delete
,在编写“真实世界的代码”时使用智能指针。更清楚的是,它从一开始就是未定义的行为。它可能不会在任何可观察的事物中表现出来(即,它可能会继续做“正确的事情”)直到后来,但它仍然是未定义的行为。但它也可能在你“达到”代码之前就显现出来:@MaxLanghof:yes,这种特殊类型的错误的痛苦是多方面的,痛苦的。只是比种族条件稍微好一点。。。