"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.
Author by
Vanidad Velour
Updated on May 02, 2020Comments
-
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 about 8 yearsavoid writing
using namespace std
. -
xaxxon about 8 yearsexcept 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 about 8 yearsWhat is the reason for the pointer usage? You wrote everything, then for some reason introduced a
Player *
into your program. Why? -
Destructor about 8 years@xaxxon: why it should never be put in .h file of real code? What's wrong with it ?
-
xaxxon about 8 yearsBecause 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 about 8 yearsI'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 about 8 yearsThanks! 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 about 8 yearsunless 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 about 8 yearsIf 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 over 3 yearsImagine 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 over 3 yearsIf 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.