【问题标题】:why is the address the same? [duplicate]为什么地址一样? [复制]
【发布时间】:2020-06-02 15:04:15
【问题描述】:

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

【问题讨论】:

  • temp 需要是动态分配的指针变量(例如使用malloc)而不是本地变量。
  • 为什么你认为每次都应该不一样?

标签: c++ memory linked-list


【解决方案1】:

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

因为您获得地址的对象具有自动存储期限。这意味着对象生命周期在它创建的块结束时结束(在你的情况下是循环结束),之后你有悬空指针。由于在对象生命周期结束后被认为是空闲的内存,编译器会出于实际目的再次重用相同的内存(它不是必须的,但它可以而且有意义)。

要使其正常工作,您应该创建具有动态存储持续时间的对象,这意味着您可以控制对象的生命周期。您可以为此使用运算符new,但最好使用智能指针而不是原始指针并让它管理对象生命周期。在这种情况下,您应该使用std::make_uniquestd::make_shared 取决于您想要什么样的所有权。你可以在这里找到详细的操作方法C++ Linked list using smart pointers

【讨论】:

    【解决方案2】:

    在插入后打印地址和 llist.add_ele_to_beg(&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)
    }
    

    因此 temp 在堆栈顶部创建,然后您对其执行一些操作,然后它超出范围(因此被销毁),然后堆栈处于与之前相同的状态循环的迭代。然后重复这个过程。

    看起来您可能的意思是使用new 分配一个新节点,以便在堆上创建对象。然后,您可以调用 list.add_ele_to_beg() 将其添加到列表中,并且该对象将存在于循环主体的末尾之外。

    【讨论】:

      【解决方案3】:

      您可以在每个循环周期中使用new Node() 创建一个新元素。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-13
        • 2020-05-12
        • 2015-12-23
        相关资源
        最近更新 更多