2

When I write my code in this way about the next one, it will return strange error.

struct Student{
    int val;
    Student* next;
    Student(int a){
        val = a;
        next = NULL;
    }
};
int main(){
Student begin(0);
Student *head = &begin;
Student *pointer = head;
for(int i=0;i<3;i++){
    pointer->val = i;
    Student next(0);
    pointer->next = &next;
    pointer = pointer->next;
}

while(head != NULL){
    cout<< head-> val<<endl;
    head = head ->next;
}
}

After I change the loop into this way, it works.

for(int i=0;i<3;i++){
    pointer->val = i;
    pointer->next = new Student(0);
    pointer = pointer->next;
}

Why this happen? Any differences between these two ways to initialize the next node?

OregonTrail
  • 8,594
  • 7
  • 43
  • 58
Xavier Cheng
  • 37
  • 1
  • 3

4 Answers4

4

You are setting up the node to point to a local stack variable, which is getting destroyed as you go to the next iteration of the for loop.

Your usage of new Student fixed this by making a heap allocation

Lots of good discussion on Heap vs Stack memory at Stack Memory vs Heap Memory

Community
  • 1
  • 1
tinkertime
  • 2,972
  • 4
  • 30
  • 45
3

When you declare a student like this

Student next(0);

It allocates temporary memory on the stack that should only be considered usable within that block.

When you use new you allocate memory on the heap that can be used anywhere. Watch out for memory leaks and always define destructors.

new Student(0);
OregonTrail
  • 8,594
  • 7
  • 43
  • 58
3
for(int i=0;i<3;i++){
   pointer->val = i;
   Student next(0);
   pointer->next = &next;
   pointer = pointer->next;
}

You are creating object student on automatic storage (commonly implemented as a stack). Then you are storing a pointer to this object in your linked list. When 'Student' goes out of scope the object is deleted. Now your pointer is a dangling pointer. De-referencing that pointer is now undefined behavior.

pointer->next = new Student(0);

Is created on dynamic storage (commonly implemented as a heap). This object will live until you tell it to die (delete it).

I suggest you read about the differences between the stack/heap in C++. It is a very important topic if you want to learn C++.

Also, make sure you deleted anything newed objects! If you don't you will end up with memory leaks in your programs.

user3853544
  • 581
  • 3
  • 9
  • Reading about the differences between the "stack" and "heap" in C++ should also involve material that explains how those two words are vague and/or incorrect. – Christian Hackl Jan 13 '17 at 21:51
1

By doing

Student next(0);

You are allocating the object on the stack.

With

new Student(0);

You are allocating the object in the heap.

Once you are leaving the scope, you will be accessing memory which is no longer yours and can be overwritten by other functions.

Doron Yakovlev Golani
  • 5,188
  • 9
  • 36
  • 60
  • I just want to comment on the stack being wiped. The data is not deleted the moment the object goes out of scope. It is simply made available for other memory to overwrite it. It may or may not exist kind of like a Schrodinger's data. – user3853544 Jan 13 '17 at 19:43
  • 1
    No. That's not true. The fact is you *can't* know what happens to the object once it goes out of scope. It *may* linger, it *may* be freed and overwritten with zeroes or garbage - you just don't know. What you *do* know is that it is Undefined Behaviour what happens if you try to access it once its lifetime has ended, so you simply should not do that. What *actually* happens depends entirely on your platform and compiler. – Jesper Juhl Jan 13 '17 at 19:52
  • I agree that my description was not accurate... so I've edited my answer. – Doron Yakovlev Golani Jan 13 '17 at 20:06
  • @DoronYakovlev-Golani: It's still incorrect. Accessing memory which is no longer yours and which can be overwritten by other functions is what **may** happen. Your answer sounds as if it would be certain. There may not even be any memory access at all. – Christian Hackl Jan 13 '17 at 21:49
  • @Christian-Hackl, I think my current answer reflects what you mentioned. Once you go out of scope, that memory does not belong to you (even though you keep the pointer to it). That is certain. If you are not accessing it, nothing wrong would happen, but that was not the question. Accessing it, however, is definitely wrong (even though in some cases you may be spared the problematic behavior). – Doron Yakovlev Golani Jan 13 '17 at 21:59
  • @DoronYakovlev-Golani: My point is that talking about memory which may or may not belong to you is already on a lower level than the C++ rules which specifiy undefined behaviour in this case. C++ doesn't even have a concept of "memory that doesn't belong to you". From a C++ point of view, when you try to call a member function on an object which has gone out of scope, then you simply do not know what will happen next. Your answer still says that *"accessing memory which is no longer yours"* is what will happen next. And that's wrong, because it's just one possibility, albeit a very likely one. – Christian Hackl Jan 13 '17 at 22:08