Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.7k views
in Technique[技术] by (71.8m points)

C++ why is my pointer taking me to some weird location as soon as I call a->val?

I'm working through a LeetCode problem with two linked lists that need to be added up.

It looks like my code is correctly generating a new list, with the expected nodes 7, and 9, followed by null, yet when I try to print out the results I'm running into an issue. I can see that the value of a->val is 7, but as soon as I get to the cout << a->val; line, it turns into another value. enter image description here

enter image description here

Why is this happening?

using namespace std;



struct ListNode {
    int val;
    ListNode* next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode* next) : val(x), next(next) {}
};



ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode ans;
    ListNode* ptr = &ans;
    int carry = 0;

    while (l1 || l2) {
        int a = 0;
        int b = 0;

        if (l1) {
            a = l1->val;
            l1 = l1->next;
        }

        if (l2) {
            b = l2->val;
            l2 = l2->next;
        }

        ptr->val = (a + b) % 10 + carry;
        carry = (a + b) / 10;

        if (l1 || l2) {
            ptr->next = new ListNode();
            ptr = ptr->next;
        }
    }

    return &ans;
}

int main()
{
    ListNode b(2);
    ListNode c(7);

    ListNode l1(2, &b);
    ListNode l2(5, &c);

    ListNode* a = addTwoNumbers(&l1, &l2);

    while (a) {
        cout << a->val;
        a = a->next;
    }
    cout << endl;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

ans is allocated on the stack, locally. As soon as you return from addTwoNumbers, there is no guarantee the data is still there, i.e. it's undefined behavior. GCC warns about it:

<source>: In function 'ListNode* addTwoNumbers(ListNode*, ListNode*)':
<source>:45:12: warning: address of local variable 'ans' returned [-Wreturn-local-addr]
   45 |     return &ans;
      |            ^~~~
<source>:18:14: note: declared here
   18 |     ListNode ans;
      |              ^~~

So, you must declare ans on the heap, using new:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode* ans = new ListNode();
    ListNode* ptr = ans;

// ...

    return ans;
}

It now runs and outputs a result.

However, as the other answer has pointed out, you're leaking memory. While it probably won't be a problem for a LeetCode problem, it's a problem for real-life code. Using an smart pointer, such as std::unique_ptr, or doing your own RAII wrapper, would be preferable solutions over calling delete for each pointer on the list.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...