"Read Access Violation: This was nullptr" Thought I assigned it correctly...?

29,253
void test(Player *player) {
    ...
    player = new Player(...);
}

That only changes the local copy of player. To change the pointer outside the function you need to take a reference to the pointer (or a double pointer). Use:

void test(Player *& player) {...}

instead.

Share:
29,253
Vanidad Velour
Author by

Vanidad Velour

Updated on May 02, 2020

Comments

  • Vanidad Velour
    Vanidad Velour about 4 years

    I have a Player Class that holds the name of the player, right answers,and wrong answers the player's gotten. When I try to access getRight(), getWrong(), addToRight(), or addToWrong() functions I get an error that says, "Read access violation: this was nullptr" at the statements inside of those functions. I must not be setting my pointer correctly. What changes should I make? Thanks!

    Here's the Player.h file

    #ifndef PLAYER_H
    #define PLAYER_H
    #pragma once
    
    using namespace std;
    class Player;//FWD declaration
    
    class Player
    {
    public:
        Player();
        Player(string playerName);
    
        string getName() const
        {
            return name;
        }
    
        //These functions show stats from
        //current round
        int getRight() const
        {
            return right;
        }
    
        int getWrong() const
        {
            return wrong;
        }
    
       //These functions update
       //player info that will be saved
       //to player profile
       void setName(string userName);
       void addToRight();
       void addToWrong();
    
    private:
         string name;
         int right;
         int wrong;
    };
    #endif
    

    Here is the Player.cpp file:

    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include "Player.h"
    
    using namespace std;
    
    Player::Player()
    {
        name = "";
        right = 0;
        wrong = 0;
    }
    
    Player::Player(string playerName)
    {
        ifstream inFile;
        ofstream outFile;
        string name = playerName;
        string fileName = playerName + ".txt";
    
        inFile.open(fileName.c_str());
        if (inFile.fail())
        {
            outFile.open(fileName.c_str());
            outFile << 0 << endl;
            outFile << 0 << endl;
            outFile.close();
            inFile.close();
            setName(playerName);
            right = 0;
            wrong = 0;
    
            cout << "Welcome new player!"
                << " Your statistics profile has been created." << endl;
        }
        else
        {
            inFile >> right;
            inFile >> wrong;
            inFile.close();
            setName(playerName);
            cout << "Welcome back!" << endl;
        }
    }
    
    void Player::setName(string userName)
    {
        name = userName;
    }
    
    void Player::addToRight()
    {
        right = right + 1;
    }
    
    void Player::addToWrong()
    {
        wrong = wrong + 1;
    }
    

    And here's my main:

    #include <iostream>
    #include <string>
    #include "Player.h"
    
    using namespace std;
    
    void test(Player *player);
    
    int main()
    {
        Player *player = nullptr;
    
    
        test(player);
    
        cout << "name: " << player->getName() << endl;
        cout << "right: " << player->getRight() << endl;
    
        player->addToRight();
    
        cout << "right: " << player->getRight() << endl;
    
        return 0;
    }
    
    void test(Player *player)
    {
        string name;
    
        cout << "name: ";
        getline(cin, name);
        player = new Player(name);
    }
    

    Does a class have to be set up differently when dealing with pointers to avoid these access violations? Thanks!

    • Destructor
      Destructor about 8 years
      avoid writing using namespace std .
    • xaxxon
      xaxxon about 8 years
      except for in examples you post to stack overflow.. then it's fine. Also, if you only put it in .cpp files, it's not nearly as bad -- just never put it in the .h file of real code.
    • PaulMcKenzie
      PaulMcKenzie about 8 years
      What is the reason for the pointer usage? You wrote everything, then for some reason introduced a Player * into your program. Why?
    • Destructor
      Destructor about 8 years
      @xaxxon: why it should never be put in .h file of real code? What's wrong with it ?
    • xaxxon
      xaxxon about 8 years
      Because it infects all other .h files you #include after it -- including things that include your .h file and then other things. Namespaces avoid naming conflicts, but if you force your "using" directive on a third-party library, it may then have conflicts and cease to compile due to ambiguous symbols (in std:: and in this library) -- in short, get used to typing std:: it's not that hard.
    • Vanidad Velour
      Vanidad Velour about 8 years
      I'll look in to that. Thanks. The class I'm taking, my professor, and the book we're reading from all set programs up this way. I can certainly move away from this practice.
  • Vanidad Velour
    Vanidad Velour about 8 years
    Thanks! I have a follow up question, just trying to wrap my head around this: I was under the impression that passing a pointer to a function directed that function to a memory address. I mean that a copy wouldn't be made of the parameter argument but any changes would be made directly to the value stored at that address. Is player copied inside the test function?
  • xaxxon
    xaxxon about 8 years
    unless you pass by reference, everything in C++ (and always everything in C) is pass by value -- which makes a copy. In this case, the copy of the POINTER is made. The copy of the pointer can modify the contents that it points to just as much as the original pointer, but modifying the pointer itself is just modifying the copy. original_ptr->some_int_field=1; and copy_of_original_ptr_in_function->some_int_field=1; both do the same thing. original_ptr = &some_player_object; only affects original_ptr and copy_of_original_ptr_in_function = &some_player_object only affects the copy.
  • xaxxon
    xaxxon about 8 years
    If you passed a pointer to a pointer (a double pointer), that would allow you to change the thing the original pointer points to, but references tend to be easier to work with and have the advantage of not being able to be null - which is appropriate in your situation.
  • xaxxon
    xaxxon over 3 years
    Imagine this - I have the address of my house written down on a piece of paper. I have a poor memory, so I need to hold on to mine, but I make a photocopy of that piece of paper and hand it to you. If you write a new house number on your copy of that paper, I still know how to get to my house with my original. But if instead you go to my house and paint it red, then the actual house is red - no matter whose copy of the address you use to go to that house.
  • xaxxon
    xaxxon over 3 years
    If instead we somehow share that piece of paper and both start driving and you change the address on that shared piece of paper, then we both end up at a different house.