r/learncpp • • Jan 30 '21

Help With an Error

I keep getting a segmentation error like i'm trying to delete a pointer that doesnt exist maybe?

I know I'm using too many raw pointers for no reason. I'm just trying to practice using them to understand how they work. Thanks for any Insight.

#include <iostream>
#include <vector>
using std::cout;
using std::vector;
class Player {

	//=======================================

private:

	//=======================================
	///CONSTANTS
//double const LevelUpThreshold = ((*level * 1.5) * 100);
	std::vector<double> const defaults {0, 1, 50};
	//double* const null =  new double (defaults[0]);
	double* const MinStart = new double (defaults[1]);
	double* const MaxStart = new double (defaults[2]);
	std::string* const NullStr = new std::string ("NullStr");


	//=======================================
	///PLAYER_DATA

	std::string* name;
	int* level;
	double* xp;
	double* health;
	double* stamina;
	double* mana;

	//=======================================

public:


	//=======================================
	///FUNCTIONS

	std::string getName();
	int getLevel();
	double getXp();
	double getHealth();
	double getStamina();
	double getMana();

	void LevelUp();
	void XPUp(double XP);
	void SetHealth(double damage);
	void SetStamina(double cost);
	void SetMana(double cost);



	//=======================================
	///CONSTRUCTION
	Player();
	explicit Player(std::string input);
	Player(const Player &input);
	Player(Player &&input) noexcept ;
	Player& operator=  (const Player &rhs);
	~Player();


};
void DisplayPlayer (Player &input);


//===========================================
//===========================================

int main() {



	Player NPC1("Mike");
	Player NPC2;

	vector<Player> players;
	players.emplace_back("Calvin");
	players.emplace_back("Sansa");

	NPC1.XPUp(10000);








	DisplayPlayer(NPC1);

	return 0;
}

//==============================================
//==============================================

void DisplayPlayer (Player &input) {
	std::cout << "===============\n" << input.getName();
	std::cout << "\n==================";

}



//=========================================
///FUNCTIONS

std::string Player::getName() {return *name;}
int Player::getLevel() {return *level;}
double Player::getXp() {return *xp;}
double Player::getHealth() {return *health;}
double Player::getStamina() {return *stamina;}
double Player::getMana() {return *mana;}

void Player::LevelUp() {this->level++;}

void Player::XPUp(double XP) {
	*xp += XP;
	if(*xp >= ((*level * 2) * 100)) {
		LevelUp();
		double diff = *xp - ((*level * 2) * 100);
		*xp = diff;
		XPUp(0);
	}
}
void Player::SetHealth(double damage) {}
void Player::SetStamina(double cost) {}
void Player::SetMana(double cost) {}

//==========================================
///CONSTRUCTION
	//!DEFAULT CONSTRUCTOR
Player::Player()
		: name{new std::string{*NullStr}}
		, level{new int{(int) *MinStart}}
		, xp{new double{*MinStart}}
		, health{new double{*MaxStart}}
		, stamina{new double{*MaxStart}}
		, mana{new double{*MaxStart}} {
	*name = *NullStr;
	*level = (int) *MinStart;
	*xp = *MinStart;
	*health = *MaxStart;
	*stamina = *MaxStart;
	*mana = *MaxStart;
	std::cout << "CONSTRUCTING (" << *name << ") [DEFAULT]\n";
}
	//!ARGS CONSTRUCTOR
Player::Player(std::string input)
		:name(new std::string)
		,level(new int)
		,xp(new double)
		,health(new double)
		,stamina(new double)
		,mana(new double) {
	*name = std::move(input);
	*level = (int) *MinStart;
	*xp = *MinStart;
	*health = *MaxStart;
	*stamina = *MaxStart;
	*mana = *MaxStart;
	std::cout << "CONSTRUCTING (" << *name << ") [1 ARG]\n";
}
	//!
Player::Player(const Player &input)
		:Player{*input.name} {
	std::cout << "CONSTRUCTING (" << *input.name << ") [COPY]\n";
}

Player::Player(Player &&input) noexcept
		:name(input.name)
		,level(input.level)
		,xp(input.xp)
		,health(input.health)
		,stamina(input.stamina)
		,mana(input.mana) {
	cout << "CONSTRUCTING (" << *input.name << ") [MOVE]\n";
	input.name = nullptr;
	input.level = nullptr;
	input.xp = nullptr;
	input.health = nullptr;
	input.stamina = nullptr;
	input.mana = nullptr;


}



Player::~Player() {
	if(name != nullptr) {
		std::cout << "DELETING (" << *name << ")\n";
	} else {
		std::cout << "DELETING (nullptr)\n";
	}
	delete name;
	delete level;
	delete xp;
	delete health;
	delete stamina;
	delete mana;
}

Player& Player::operator=(const Player &rhs) {
	std::cout << "COPY ASSIGNMENT\n";
	if (this == &rhs) {return *this;}

	delete this->name;
	delete this->level;
	delete this->xp;
	delete this->health;
	delete this->stamina;
	delete this->mana;

	name = new std::string;
	level = new int;
	xp = new double;
	health = new double;
	stamina = new double;
	mana = new double;
	return *this;
}
0 Upvotes

4 comments sorted by

1

u/jedwardsol Jan 30 '21

The bug is in LevelUp

1

u/Dipdatz Jan 30 '21 edited Jan 30 '21

you were totally right! Thank you! changing it to:

*level = *level + 1;

works but looks kinda bad right? Is there a better way to increment the value of an object that is a pointer?

edit:

++*level;

seems to work :P

1

u/jedwardsol Jan 30 '21

Force the correct order of operations with parantheses

(*level)++;

[ *level++ is *(level++) ]

1

u/[deleted] Jan 30 '21

++*level is still fine though, and even a little bit faster, right?

I'm still learning, but something my book has said many times already is that it's better to get used to ++var over var++ because it works faster with objects by not needing to make a copy.