I'm trying to improve my C++ by writing a game of Conway's life.
The GameBoard object is getting corrupted. I call its print() method directly from the Game object constructor and it works. I then call it indirectly via from Game's print_board method and get an error on an integrity check.
Also, in main, there is a declaration of a variable I never use, but if I remove it, the error goes away. Somehow, I'm doing something to corrupt memory. It's probably pretty obvious.
Any assistance is greatly appreciated!
#include <iostream>
using namespace std;
class Board {
int size;
int grid[100][100];
public:
Board(int board_size) {size = board_size;}
void print() {
cout << "Board::print()" << endl;
if (size < 1) {cout << "print: size must be > 0: size=" << size << "\n"; exit(1);}
}
};
class GameRuleSet { }; // Methods removed
class Game {
private:
Board * game_board;
GameRuleSet * rule_set;
public:
Game (GameRuleSet * p_rule_set, int p_board_size) {
Board * game_board = new Board(p_board_size);
cout << "Second Call - indirect..." << endl;
game_board->print();
cout << "Second Call - direct..." << endl;
this->print_board(); // Error manifests from here
}
void print_board() {game_board->print();}
};
int main () {
int num_turns = 10; // This line manifests error.
int board_size = 10;
GameRuleSet rule_set = GameRuleSet();
Game game = Game(&rule_set, board_size);
}
You are re-declaring "Board* game_board" in your constructor which shadows the member variable of the same name. It then uses that allocated local game_board in the constructor to print.
In the print_board() function it uses the unallocated member and therefore throws the error.
Change the allocation from
Board * game_board = new Board(p_board_size);
to
game_board = new Board(p_board_size);
in the constructor to fix this.
Related
I am just started learning OOP concepts and to help myself learning, I have created a Characters class. From this class I have made instance called main and an instance called monster. Here is the code for the class:
#include <iostream>
#include <string>
using namespace std;
class Character {
public:
string name;
float health;
int attackLevel;
int defenseLevel;
void setAttr(string sName,float sHealth, int sAttackLevel, int sDefenseLevel) {
name = sName;
health = sHealth;
attackLevel = sAttackLevel;
defenseLevel = sDefenseLevel;
}
void attack(int whatInstanceToAttack) {
whatInstanceToAttack.hitpoints -= 20; //obviously not valid but how do i do this?
return whatInstanceToAttack;
}
int defend(string defend) {
int damageRelieved = defenseLevel * 2;
return damageRelieved;
}
};
int main() {
Character main;
Character monster;
main.setAttr("Rafael",200,100,30);
monster.setAttr("Monster1",30,40,30);
cout << "Default Values for Raf are;" << endl;
cout << main.name << endl;
cout << main.health<< endl;
cout << main.attackLevel << endl;
cout << main.defenseLevel << endl;
cout << "Default values for monster are" << endl;
cout <<monster.name << endl;
cout <<monster.health << endl;
cout << monster.attackLevel<< endl;
cout << monster.defenseLevel << endl;
return 0;
}
Basically what I want to do is somehow access the monster instance via the main instance. I want to do this by running the attack method. So if I run
main.attack(monster);
then I want the monster to lose 20 hitpoints.
How do I go about doing this?
All you need is to pass reference of Character in attack method.
I think you must be aware of pass by value and pass by reference concept. If not you can read it here
void attack(Character &whatInstanceToAttack) {
whatInstanceToAttack.hitpoints -= 20; //obviously not valid but how do i do this?
}
Yes you can access the variables of an instance from another instance of the same class. You need to use a reference to the object to ensure the changes are reflected in the other instance. So here is what your attack function should look like.
void attack(Character &c)
{
c.hitpoints - = 20;
}
Now when you call main.attack(monster) from the main() function, the hitpoints of monster will get decremented by 20.
As a side note, it is considered a good practice to make the data members of a class private, to avoid illegal access/modification of the data. Always use the member functions as an interface to your class instances.
overload the method attack and you can pass by value or reference as per your requirement.
void attack(Character chr)
or
void attack(Character &chr)
I have a problem. I want to operate with single element of an array, which is generated in member function, but it doesn´t work. Here is my code:
using namespace std;
class Example
{
public:
int *pole;
void generate_pole();
};
void Example::generate_pole()
{
int *pole = new int [10];
for (int i = 0; i < 10; i++)
{
pole[i] = i;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Example reference;
reference.generate_pole();
cout << reference.pole[1] << endl; //there is the problem
system("pause");
return 0;
}
How can I get an access to the element? And where is the real problem? Thank you!
int *pole = new int [10]; is creating an identically named variable pole in local scope. This is shadowing the member variable.
A fix, drop the int* from the errant line: pole = new int [10];
That said, I'd be inclined to use a constructor to set the member variable in this case: certainly you should initialise pole to nullptr by default. This is so you can delete[] pole in a destructor when an instance of your class goes out of scope. Else your code will leak memory like a colander leaks water.
An other way would be to use std::vector<int> pole; and let the C++ standard library take care of all the memory for you.
The problem is, that you shadow pole's name in the scope of the function by redeclaring it. leave the int * in front of pole behind, in generate_pole, and it should work.
An example for shadowing:
int i = 0; // i is 0
std::cout << "before scope: " << i << std::endl; // prints 0
{
int i = 1;
std::cout << "inside scope: " << i << std::endl; // prints 1
}
std::cout << "behind scope: " << i << std::endl; // prints 0
I have here some line of code. What I am trying to do here is that I would like to allocate 10 objects using overloaded operator new and on the 11th "run out of memory" and throw an exception. I added a static member function that reclaims the memory allocated for the 10th object so that I can use the address back and allocate it to a new object.
I'm still on the learning process for c++ so your critics are highly appreciated.
Help me evaluate my program. I don't know how I can reclaim the memory and then use the address to allocate the next new object.
Thank you.
P.S. how can I use 'this' in overload operator new?
#include <iostream>
#include <cstdlib>
using namespace std;
int count=0;
class RunOutOfMemory : public exception{
public:
const char * Message(){
return "Run out of memory!";
}
};
class ObjectAllocation{
public:
ObjectAllocation(){
cout << count << "Object Allocated at " << &this[count] << endl;
}
//Operator new overloaded
void * operator new(){
count++;
if(count>=11){
throw RunOutOfMemory();
}
}
//Reclaim memory allocated for 10th instance
//so that a new object can be instantiate on its memory address
static void reclaim(){
//delete?
}
};
int main(int argc, char * argv[]){
ObjectAllocation * objAlloc;
int counter=0;
cout << &objAlloc << endl;
while(counter<=20){
counter++;
try{
objAlloc = new ObjectAllocation();
cout << &objAlloc[counter] << endl;
}catch(RunOutOfMemory room){
cout << room.Message() << endl;
objAlloc.reclaim();
}
}
}
I'm trying to figure out how I can or why I can't access the member of this class. First I'll show you what works so you know what I'm thinking, then I'll show you what I can't seem to do.
What I can do is this: I have a class with a member. I make an pointer array of that class and make NEW pieces of it (through loop) and that's fine and all. I can also make another class with a similar array and even make NEW instances of that as well and initialize them, but when I try to access them, I have problems.
This code almost works fine:
#include <iostream>
using namespace std;
class testClass{
public:
int number;
};
class testPoint{
public:
testClass testInstance;
testClass *testclassArray[5];
void makeArray();
void setToI();
};
void testPoint::makeArray(){
for (int i = 0; i < 5; i++){
testclassArray[i] = new testClass;
}
}
void testPoint::setToI(){
for (int i = 0; i < 5; i++){
(*testclassArray[i]).number = i;
}
}
int main(void){
testPoint firstTestPoint;
firstTestPoint.makeArray();
firstTestPoint.setToI();
// EXCEPT FOR THIS LINE this is where I have problems
cout << firstTestPoint.(*testclassArray[0]).number << endl;
return 0;
}
I know this should work becuase this works
int main(void){
testPoint firstInstance;
firstInstance.testInstance.number = 3;
cout << firstInstance.testInstance.number << endl;
// and this works
return 0;
}
and this works
int main(void){
testClass *testPointer[5];
for (int i = 0; i < 5; i++){
testPointer[i] = new testClass;
(*testPointer[i]).number = i;
}
cout << (*testPointer[0]).number << endl;
return 0;
}
so why can't I access the members on the cout function the same way?
The following is invalid syntax:
cout << firstTestPoint.(*testclassArray[0]).number << endl;
The most common way to write what you are trying to accomplish is:
cout << firstTestPoint.testclassArray[0]->number << endl;
But, if you prefer, you can also write:
cout << (*firstTestPoint.testclassArray[0]).number << endl;
(The second way is far less common.)
The . operator is used to access members of direct objects, e.g. a.member where a might be declared as struct A a;. The -> operator is used to access members of indirect objects (aka pointers to objects), e.g. b->member where b might be declared as struct B* b = new B();.
You are dereferencing the variable in an incorrect way.
Try doing
cout << firstTestPoint.testclassArray[0]->number << endl;
instead.
In the same way the second attempt, where it works for you, could also have been written:
out << testPointer[0]->number << endl;
Try using this code:
cout << firstTestPoint.testclassArray[0]->number << endl;
So I'm working on a program which is a game of Blackjack. I have a class called Player for each player in the game. The problem lies in this block of code here which is inside Player.cpp:
void Player::SetFunds(int amt){
cout << "setting funds:" << endl;
cout << m_funds << "m_funds" << endl;
m_funds = amt;
cout << "done" << endl;
}
When compiled, I get a segmentation fault. The line "setting funds:" prints, but I cannot print m_funds, nor can I set it to amt (I tried it before adding the print statement for m_funds).
Here's the declaration of the function in Player.h (which is included in Player.cpp).
void SetFunds(int amt);
And here is where I have m_funds, among other private variables in the Player class.
private:
char* m_name;
int m_funds;
int m_bet;
Hand m_hand;
bool m_busted;
};
Is there something I'm missing? Why can't I seem to access a private Player class variable even though I am inside a Player class function? Is it possible the error is elsewhere even though I get a segmentation fault right after the "setting funds" prints?
Also, I can change the private variables in the constructor just fine, as follows:
Player::Player(char *name, int amt){
m_name = name;
cout << amt << endl; //Amount prints as 100
m_funds = amt; // sets m_funds to 100
cout << m_funds << endl; //m_funds prints as 100 just fine
m_bet = 0;
m_hand = Hand();
m_busted = false;
}
EDIT:
Here is where I call the function SetFunds inside Blackjack.cpp:
(m_players is a vector of Players as a private variable of Blackjack class.) Again, amt couts to 100.
void Blackjack::SetPlayerFunds(int player, int amt){
cout << amt << endl;
m_players[player].SetFunds(amt);
}
And here is where I call that function from Project.cpp (which contains main):
(Note: This is for a project where I cannot edit this file and have to base my code around it)
Blackjack *CreateGame(int argc, char *argv[]) {
char **names;
int *funds;
int numPlayers;
Blackjack *game;
numPlayers = ProcessArgs(argc - 1, &argv[1], names, funds);
game = new Blackjack(names, numPlayers);
for (int p = 0; p < numPlayers; p++) {
game->SetPlayerFunds(p, funds[p]);
}
EDIT 2:
Here is the Blackjack class constructor which is called inside Blackjack::CreateGame.
Blackjack::Blackjack(char *names[], int numPlayers){
std::vector<Player> m_players;
m_dealer = Player();
int amt = 100;
for(int i = 0; i < numPlayers; i++){
Player player(names[i], amt);
m_players.push_back(player);
}
}
Your issue is in the Blackjack constructor.
Blackjack::Blackjack(char *names[], int numPlayers){
std::vector<Player> m_players;
m_dealer = Player();
int amt = 100;
for(int i = 0; i < numPlayers; i++){
Player player(names[i], amt);
m_players.push_back(player);
}
}
You are creating m_player on the heap in the constructor, assigning and adding players, but probably never initializing the real member of the same name in the class...
To solve the issue, remove the std::vector m_players;
Umm, It seems that this pointer is strange..
I suggest this test code.
void Blackjack::SetPlayerFunds(int player, int amt)
{
cout << amt << endl;
// if "m_players" is std::vector
m_players.at(player).SetFunds(amt);
// elif "m_players" is C-array
if (player >= sizeof(m_players)/sizeof(m_players[0]))
abort(); // assert(false) or setting breakpoint will be better, if you can use debugger
m_players[player].SetFunds(amt);
}