-4

I am trying to set the value of a variable contained within a struct which is being pointed to with a smart pointer.

For context:

// Represents a node in the search tree.
struct SNode
{
  int x;             // x coordinate
  int y;             // y coordinate
}

The pointer (Declared as unique_ptr<SNode>start) is called start.

I am reading in data from a file and this is the problem line:

inFile >> move(start)->x;

Upon execution, this line is executed and the following error occurs within "istream":

"Unhandled exception thrown: read access violation. _Val was nullptr."

I am fairly new to the concept of smart pointers so I don't quite know whether I'm personally doing anything wrong here, so any help is appreciated.

James
  • 69
  • 1
  • 9
  • 3
    Please provide [mcve], instead of descriptions of code. – Algirdas Preidžius Jan 17 '19 at 19:53
  • 1
    Why are you using `move()`? – melpomene Jan 17 '19 at 19:53
  • @melpomene I assumed I had to, it would appear maybe not! The problem is the same without `move()` however – James Jan 17 '19 at 19:57
  • @JamesEaston Had to? What for? – melpomene Jan 17 '19 at 19:58
  • If `move(start)->x` is a call to `std::move` then this looks *highly* suspicious to me. – Borgleader Jan 17 '19 at 19:59
  • @melpomene As I said, I'm new to this so I don't really understand things properly. I would guess at a misunderstanding of something I had been taught, no real reason though. – James Jan 17 '19 at 20:00
  • @Borgleader I have removed `move()` from the code and the same problem occurs – James Jan 17 '19 at 20:01
  • 3
    @JamesEaston Sounds like you don't understand the fundamental basics of how pointers work, let alone how smart pointers work. You have some more studying to do. – Remy Lebeau Jan 17 '19 at 20:02
  • 1
    We could possibly explain this if you provided a minimal example. At the moment there is not enough context. – drescherjm Jan 17 '19 at 20:05
  • 1
    You shouldn't need to use `move` unless you want to transfer ownership of the pointer. Any other time you find yourself having to `move` a `unique_ptr`, the alarm bells should sound. There are a few other reasons, but they're pretty rare. – user4581301 Jan 17 '19 at 20:15
  • @RemyLebeau Well from what I know, a pointer is a variable which stores the memory address of another variable, so for example `xPtr` is a pointer to an integer called `x`. The value of `x` may be 3 but the value of `xPtr` would be the memory address of `x`. Am I right in thinking this? – James Jan 17 '19 at 20:17
  • 1
    You are correct, but you also have to know that `xPtr` doesn't have to point to anything meaningful. If you don't assign it an address, it's a ticking timebomb. If you assign it an address that is later rendered invalid (`delete`ed or went out of scope) it's a ticking timebomb. The worst thing is when it blows up, you might not even recognize it. Just because your program isn't using a piece of memory anymore (or never pointed the pointer in the first place) doesn't mean that it's gone, that it isn't assigned to something else, or that the data that was in that memory has been changed yet. – user4581301 Jan 17 '19 at 20:29
  • All manner of bad can happen if you access an invalid pointer. An access violation or other program crash is actually one of the nicest outcomes. Often you'll find some apparently random other variable gets trampled over, leading you off on a wild goose chase, investigating the wrong part of the program and possibly months after the real bug manifested. – user4581301 Jan 17 '19 at 20:31
  • More useful reading: [What is ownership of resources or pointers?](https://stackoverflow.com/questions/49024982/what-is-ownership-of-resources-or-pointers) – user4581301 Jan 17 '19 at 20:35

1 Answers1

3

A smart pointer holds a raw pointer, so it needs to point at something. The error clearly says it is pointing to nothing. Do you have a new or std::make_unique<> statement anywhere in your code?

You need something like this:

unique_ptr<SNode> start(new SNode);

Or:

unique_ptr<SNode>start = std::make_unique<SNode>();
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
andre
  • 155
  • 9
  • 1
    That has worked perfectly! So using `(new SNode)` creates a new instance of `SNode` called `start`? – James Jan 17 '19 at 20:12
  • 1
    @JamesEaston That's the right idea. It does create an instance but start is a smart pointer that hold onto that instance. – andre Jan 17 '19 at 20:20
  • Ah that makes a great deal of sense, thank you very much! – James Jan 17 '19 at 20:22