My objects' members change when I call their methods

0

I have an object in C++ with several properties initially set to nullptr, the idea being that I can tell when I reach the edge of what I have thus far defined. For example, I can chain Nodes together into a linked list, and detect the end of the list by comparing to nullptr:

class Node{
public:
  Node* next;
  bool val;
  Node(bool v){val=v; next=nullptr;}
  void append(bool v){
    if (next==nullptr){
      next=&Node(v);
    }else{
      next->append(v);
    }
  }
}

The problem being that I keep getting Read Access Violations. When I step through line-by-line in Visual Studio, I see the same thing immediately before every failure: in one stack frame next is set up properly, with 0x00000000 for its own successor, but when I call next->append(v);, suddenly next is a random pointer like 0x01010101 or 0x00000001, which isn't nullptr, and so the code tries to call append on it and dies because that address does not hold a Node. To Recap: *next.next==nullptr, but after calling next.append(v); something changes and next!=nullptr.

c++
asked on Stack Overflow Jun 28, 2020 by Necronophtase

1 Answer

3

The solution here is to dynamically allocate that object. You're using a temporary which falls out of scope on the very next line, and any references to that are invalidated, meaning your next pointer is now garbage.

The easy fix is:

void append(bool v) {
  if (next == nullptr) {
    next = new Node(v);
  } else {
    next->append(v);
  }
}

Where that does an allocation using new and places that value appropriately.

It's important to note that when you allocate with new your code is responsible for releasing that memory with delete. In other words, you are now obligated to create a destructor that unwinds all of your allocations.

It's worth noting that your constructor isn't correctly expressed, it should look like:

Node(bool v) : val(v), next(nullptr) { }

Where that makes use of constructor lists. This ensures that the values aren't first defaulted and then immediately assigned by effectively re-defining what the defaults are.

answered on Stack Overflow Jun 29, 2020 by tadman

User contributions licensed under CC BY-SA 3.0