为什么地址相同?

时间:2020-06-02 15:04:15

标签: c++ memory linked-list

为什么每次循环运行时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;
}

3 个答案:

答案 0 :(得分:5)

为什么每次循环运行时temp的地址(在主循环中的while循环中)都相同

因为您获得的对象的地址具有自动存储期限。这意味着对象生命期在创建它的块的末尾(在本例中为循环的结尾)结束,并且在那之后您还悬空了指针。由于在对象的生存期结束后认为该内存可用,所以编译器出于实际目的再次重用了同一内存(它不是必须的,但是可以并且很有意义)。

要使其正常工作,应创建具有动态存储持续时间的对象,这意味着您可以控制对象的生存期。您可以为此使用运算符::w,但是最好使用智能指针而不是原始指针,并让它管理对象的生存期。在这种情况下,应根据需要的所有权类型使用::a::wnew。您可以在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()创建一个新元素。