为什么每次循环运行时temp的地址(在main的while循环中)都相同 我试图插入到链表中,然后显示然后输出中间元素,但最初在显示它时会发生无限循环,仅显示第一个元素。在插入和llist.add_ele_to_beg(&temp);之后打印地址。每次都向同一地址致意!为什么会这样?
#include<iostream>
#include <unistd.h>
using namespace std;
class LinkedList;
class Node
{
private:
Node* next;
int value;
friend class LinkedList;
public:
Node(int ele) // constructor - declared in private section
// to prevent other classes creating objects of this class,
// only this class can create the object
{
next = nullptr;
value = ele;
}
};
class LinkedList
{
private:
Node* head;
public:
LinkedList()
{
head = nullptr;
}
void add_ele_to_beg(Node *temp)
{
// Node *temp = new Node(); // dynamically alloctg Node object
// temp->value = x;
temp->next = this->head;
this->head = temp;
}
void display()
{
Node *h = this->head;
while(h)
{
cout << h << endl;
cout << h->value << endl;
h = h->next;
cout << h << endl;
cout << h->value << endl;
exit(0);
}
}
int findMiddle()
{
Node *fast, *slow = this->head;
if(!slow)
{
return -1;
}
if(!slow->next)
{
return slow->value;
}
if(!slow->next->next)
{
return slow->value;
}
// n > 2
fast = head->next->next;
while(1)
{
slow = slow->next;
if(!fast->next)
{
if(!fast->next->next)
{
fast = fast->next->next;
}
else
{
break;
}
}
else
{
break;
}
}
return slow->value;
}
};
int main()
{
LinkedList llist;
int n;
cout << "enter n" << endl;
cin >> n;
// create a dummy node
cout << "enter elements to be inserted in the beg" << endl;
int ele;
while(n--)
{
cin >> ele;
Node temp(ele); // obj node created and ctor initialises
llist.add_ele_to_beg(&temp); // sending address of node to make change to
cout << &temp << endl;
// node (passing by reference)
}
llist.display();
cout << llist.findMiddle();
cout << endl;
return 0;
}
答案 0 :(得分:5)
为什么每次循环运行时temp的地址(在主循环中的while循环中)都相同
因为您获得的对象的地址具有自动存储期限。这意味着对象生命期在创建它的块的末尾(在本例中为循环的结尾)结束,并且在那之后您还悬空了指针。由于在对象的生存期结束后认为该内存可用,所以编译器出于实际目的再次重用了同一内存(它不是必须的,但是可以并且很有意义)。
要使其正常工作,应创建具有动态存储持续时间的对象,这意味着您可以控制对象的生存期。您可以为此使用运算符::w
,但是最好使用智能指针而不是原始指针,并让它管理对象的生存期。在这种情况下,应根据需要的所有权类型使用::a::w
或new
。您可以在C++ Linked list using smart pointers
答案 1 :(得分:2)
在插入后打印地址,然后llist.add_ele_to_beg(&temp);每次都向同一地址致意!为什么会这样?
发生这种情况是因为func testAlarmPickerViewModel() {
let alarmPickerViewModel = AlarmPickerViewModel(alarm: Alarm(time: .distantFuture))
alarmPickerViewModel.$alarm.sink(receiveValue: { print("ViewModel.alarm updated, new value: \($0)") })
alarmPickerViewModel.objectWillChange.sink(receiveValue: { print("ViewModel updated: \($0)")})
}
是局部变量,所以它存在于堆栈中,并且每次循环都在同一位置创建和销毁同一组局部变量:
temp
因此,在堆栈顶部创建了temp,然后对其进行了一些处理,然后超出了范围(因此被破坏),然后堆栈处于与之前相同的状态循环的迭代。然后重复该过程。
看来您可能要执行的操作是使用while(n--)
{
cin >> ele;
Node temp(ele); // obj node created and ctor initialises
llist.add_ele_to_beg(&temp); // sending address of node to make change to
cout << &temp << endl;
// node (passing by reference)
}
分配新节点,以便在堆上创建对象。然后,您可以调用new
将其添加到列表中,该对象将位于循环主体的末尾。
答案 2 :(得分:0)
您可以在每个循环周期中使用new Node()
创建一个新元素。