Segmentation fault when trying to clean object in Gtest - c++

So, this is my test. But it has segmentation fault on the last line: m->service-> clean. And if I don't use this function, I have memory leaks. Is there any alternative?
class ServiceTest: public ::testing::Test
{
protected:
virtual void SetUp()
{
m_service = new conn::tsm::Service();
}
virtual void TearDown()
{
delete m_service;
m_service = 0;
}
// Tested Object:
conn::Service *m_service;
};
TEST_F(ServiceTest, CatchChildDelete)
{
conn::IObject_mock *testParam = new conn::IObject_mock();
m_service->setId(0x01);
EXPECT_CALL(*testParam, getId()).WillRepeatedly(::testing::Return(0x01));
EXPECT_TRUE(m_service->addObject(testParam));
EXPECT_CALL(*testParam, die()).WillOnce(::testing::Throw(std::exception()));
m_service->clean();
}
And this is the implementation of clean():
void Service::clean() throw()
{
try
{
std::vector<IObject *>::iterator it = m_objectTable.end();
for( it = m_objectTable.begin(); it != m_objectTable.end();++it )
{
delete (*it);
}
/* clear cache */
m_objectMap.clear();
m_objectTable.clear();
}
catch(...)
{
}
}

Related

GoogleTest Mocking object method call fail

Hi so this is my first time utilizing googleTest Mocking. The general setup of the project is that coffeeMachine has an object coffeeStorage and coffeeStockService that it calls methods from coffeeMachine methods. I'm trying to create a mock test for the objects coffeeStorage and coffeeStockService but it's not recognizing the Expected Calls when I assign the mock objects to the coffeeMachine instance.
Trying to implement GoogleTest's mocking test framework but it's not recognizing the EXPECTED_CALL and also not letting me use mockedCoffeeStorage as a parameter to the method calls for mockedCoffeeStockService.. StockService Expected Call is because CoffeeMachine is also calling that but I passed in the coffeeStorage as a parameter. Is that possible for a mock object to cause a method that is using another mock object as the parameter and still expect the method to be called? Should I refactor and not include all the object references to the methods for CoffeeMachine since I already declare a CofeeStorage and CoffeeStockService object? Thank you so much
class coffeeMachine {
public:
coffeeStorage* CoffeeStorage;
coffeeStockService* CoffeeStockService;
bool coffeeServed = false;
coffeeMachine(coffeeStorage* CoffeeStorage, coffeeStockService* CoffeeStockService);
void start(string langIn);
void stop();
void descale();
void showSettings();
void hideSettings();
map<string, string> getSetting();
string message(coffeeStorage& CoffeeStorage);
void takeCoffee(coffeeStorage& CoffeeStorage);
void fillTank(coffeeStorage& CoffeeStorage, coffeeStockService& CoffeeStockService);
void fillBeans(coffeeStorage& CoffeeStorage, coffeeStockService& CoffeeStockService);
void emptyGrounds(coffeeStorage& CoffeeStorage, coffeeStockService& CoffeeStockService);
bool isDescalingNeeded();
class coffeeStorage {
private:
int waterStorage;
int beanStorage;
int trashStorage;
public:
//virtual ~coffeeStorage(){}
coffeeStorage();
virtual void takeCoffeeStorage();
virtual void setWaterStorage(int amount);
virtual void setBeansStorage(int amount);
virtual void emptyTrashStorage();
virtual int checkWater();
virtual int checkBeans();
virtual int checkTrashStorage();
};
class mockCoffeeStorage : public coffeeStorage {
private:
int waterStorage;
int beanStorage;
int trashStorage;
public:
MOCK_METHOD(void, takeCoffeeStorage, (), (override));
MOCK_METHOD(void, setWaterStorage, (int amount), (override));
MOCK_METHOD(void, setBeansStorage, (int amount), (override));
MOCK_METHOD(void, emptyTrashStorage, (), (override));
MOCK_METHOD(int, checkWater, (), (override));
MOCK_METHOD(int, checkBeans, (), (override));
MOCK_METHOD(int, checkTrashStorage, (), (override));
};
coffeeMachine::coffeeMachine(coffeeStorage* CoffeeStorage_, coffeeStockService* CoffeeStockService_){
waterHardness = "2";
grinder = "medium";
started = false;
coffeeServed = false;
settingsDisplayed = false;
CoffeeStorage = CoffeeStorage_;
CoffeeStockService = CoffeeStockService_;
message(*CoffeeStorage_);
descale();
fillTank(*CoffeeStorage_, *CoffeeStockService_);
fillBeans(*CoffeeStorage_, *CoffeeStockService_);
emptyGrounds(*CoffeeStorage_, *CoffeeStockService_);
}
string coffeeMachine::message(coffeeStorage& CoffeeStorage){
if(!started) return "";
if (settingsDisplayed) return i18n("settings");
if (CoffeeStorage.checkWater() <= 10) return i18n("tank");
if (CoffeeStorage.checkBeans() < 3) return i18n("beans");
if (CoffeeStorage.checkTrashStorage() >= 30) return i18n("grounds");
if (isDescalingNeeded()) return i18n("descale");
return i18n("ready");
}
void coffeeMachine::takeCoffee(coffeeStorage& CoffeeStorage){
if (CoffeeStorage.checkWater() == 0 || CoffeeStorage.checkBeans() == 0) {
coffeeServed = false;
} else {
coffeeServed = true;
CoffeeStorage.takeCoffeeStorage();
countdownToDescale -= 1;
}
}
void coffeeMachine::fillTank(coffeeStorage& CoffeeStorage, coffeeStockService& CoffeeStockService){
CoffeeStockService.restockWater(CoffeeStorage);
}
void coffeeMachine::fillBeans(coffeeStorage& CoffeeStorage, coffeeStockService& CoffeeStockService){
CoffeeStockService.restockBeans(CoffeeStorage);
}
void coffeeMachine::emptyGrounds(coffeeStorage& CoffeeStorage, coffeeStockService& CoffeeStockService){
CoffeeStockService.emptyTrash(CoffeeStorage);
}
TEST(MockObjTest, TestObjectCallsWithMock) {
mockCoffeeStorage mockedCoffeeStorage;
mockCoffeeStockService mockedCoffeeStockService;
EXPECT_CALL(mockedCoffeeStorage, checkWater())
.Times(AtLeast(1));
EXPECT_CALL(mockedCoffeeStorage, checkBeans())
.Times(AtLeast(1));
EXPECT_CALL(mockedCoffeeStorage, takeCoffeeStorage())
.Times(AtLeast(1));
coffeeMachine coffeeTest = coffeeMachine(&mockedCoffeeStorage, &mockedCoffeeStockService);
std::cout<< "Address of mockedCoffeeStorage: " << &mockedCoffeeStorage << "\n";
std::cout<< "Address of mockedCoffeeStockService: " << &mockedCoffeeStockService << "\n";
// EXPECT_CALL(mockedCoffeeStockService, restockWater(mockedCoffeeStorage))
// .Times(AtLeast(1));
// EXPECT_CALL(mockedCoffeeStockService, restockBeans(mockedCoffeeStorage))
// .Times(AtLeast(1));
// EXPECT_CALL(mockedCoffeeStockService, emptyTrash(mockedCoffeeStorage))
// .Times(AtLeast(1));
coffeeTest.start("en");
for(int i = 0; i < 10; i++)
{
if(coffeeTest.getBeansContent(mockedCoffeeStorage) < 5)
coffeeTest.fillBeans(mockedCoffeeStorage, mockedCoffeeStockService);
if(coffeeTest.getGroundsContent(mockedCoffeeStorage) > 20)
coffeeTest.emptyGrounds(mockedCoffeeStorage, mockedCoffeeStockService);
if(coffeeTest.getTankContent(mockedCoffeeStorage) < 15)
coffeeTest.fillTank(mockedCoffeeStorage, mockedCoffeeStockService);
coffeeTest.takeCoffee(mockedCoffeeStorage);
}
}
It's perfectly fine to set expect calls one mock with other mock as a parameter.
no need to pass the objects to each method - you can access them inside your functions because they're are members. This technique is called 'dependency injection'.
See this code (using GMock 1.8, so mock definition is slightly different):
// pure virt. interface, remember about virtual dtor
class coffeeStorage {
public:
virtual ~coffeeStorage() = default;
virtual void takeCoffeeStorage() = 0;
virtual void setWaterStorage(int amount) = 0;
virtual void setBeansStorage(int amount) = 0;
virtual void emptyTrashStorage() = 0;
virtual int checkWater() = 0;
virtual int checkBeans() = 0;
virtual int checkTrashStorage() = 0;
};
class coffeeStockService {
public:
virtual ~coffeeStockService() = default;
virtual void restockWater(coffeeStorage& storeage) = 0;
};
class coffeeMachine {
public:
coffeeMachine(coffeeStorage* CoffeeStorage, coffeeStockService* CoffeeStockService);
void fillTank() {
CoffeeStockService->restockWater(*CoffeeStorage);
}
void takeCoffee() {
if (CoffeeStorage->checkWater() == 0 || CoffeeStorage->checkBeans() == 0) {
coffeeServed = false;
}
else {
coffeeServed = true;
CoffeeStorage->takeCoffeeStorage();
}
}
bool isCoffeeServed() {
return coffeeServed;
}
private:
coffeeStorage* CoffeeStorage;
coffeeStockService* CoffeeStockService;
bool coffeeServed{false};
};
coffeeMachine::coffeeMachine(coffeeStorage* CoffeeStorage_, coffeeStockService* CoffeeStockService_)
: CoffeeStorage{CoffeeStorage_}
, CoffeeStockService{CoffeeStockService_} {}
class mockCoffeeStorage : public coffeeStorage {
public:
MOCK_METHOD0(takeCoffeeStorage, void());
MOCK_METHOD1(setWaterStorage, void(int amount));
MOCK_METHOD1(setBeansStorage, void(int amount));
MOCK_METHOD0(emptyTrashStorage, void());
MOCK_METHOD0(checkWater, int());
MOCK_METHOD0(checkBeans, int());
MOCK_METHOD0(checkTrashStorage, int());
};
class mockCoffeeStockService : public coffeeStockService {
public:
MOCK_METHOD1(restockWater, void(coffeeStorage& storeage));
};
struct MockObjTest : public testing::Test {
mockCoffeeStorage mockedCoffeeStorage;
mockCoffeeStockService mockedCoffeeStockService;
coffeeMachine coffeeTest = coffeeMachine(&mockedCoffeeStorage, &mockedCoffeeStockService);
};
TEST_F(MockObjTest, When_FillingTank_Then_RestocksWater) {
// assert
EXPECT_CALL(mockedCoffeeStockService, restockWater(testing::Ref(mockedCoffeeStorage)));
// act
coffeeTest.fillTank();
}
TEST_F(MockObjTest, Given_NoWater_When_TakingCoffee_Then_CoffeeNotServed) {
// arrange
EXPECT_CALL(mockedCoffeeStorage, checkWater()).WillOnce(testing::Return(0));
// act
coffeeTest.takeCoffee();
// assert
ASSERT_FALSE(coffeeTest.isCoffeeServed());
}
TEST_F(MockObjTest, Given_EnoughWaterWaterAndBeans_When_TakingCoffee_Then_takeCoffeeStorageAndCoffeeServed) {
// arrange
EXPECT_CALL(mockedCoffeeStorage, checkWater()).WillOnce(testing::Return(1));
EXPECT_CALL(mockedCoffeeStorage, checkBeans()).WillOnce(testing::Return(1));
EXPECT_CALL(mockedCoffeeStorage, takeCoffeeStorage()); // this is more of the 'assert' part, but it cannot be moved to the end of the test
// act
coffeeTest.takeCoffee();
// assert
ASSERT_TRUE(coffeeTest.isCoffeeServed());
}
This is trimmed and simplified version of your code, but this should get you running. Always try to start with some v. easy, minimal test and build from this adding more complexity. If the tests becomes too complex/complicated, it is probably time to separate some parts of your code to the new class and test this class in separation.

C++ destructor is crashing on function pointer

I'm using Visual Studio 2017. I have a class defined thusly:
class Timer
{
friend class TimerFactory;
protected:
explicit Timer(std::function<void()>theCallback, uint theTimer, std::thread::id theThread, bool theImmediate, bool recurring) :
myCallback(theCallback), myTimer(theTimer), myThread(theThread), isImmediate(theImmediate), isRecurring(recurring), myWorkComplete(false)
{
}
Timer(const Timer& orig)
{
myCallback = orig.myCallback;
myTimer = orig.myTimer;
myThread = orig.myThread;
myWorkComplete = orig.myWorkComplete;
isImmediate = orig.isImmediate;
isRecurring = orig.isRecurring;
}
public:
~Timer()
{
}
void Start()
{
Run();
}
private:
std::function<void()>myCallback;
uint myTimer;
std::thread::id myThread;
bool myWorkComplete;
bool isImmediate;
bool isRecurring;
void Run();
};
void Timer::Run()
{
std::chrono::nanoseconds ms(myTimer);
begin: std::this_thread::sleep_for(ms);
if (!(myCallback == nullptr))
{
myCallback();
}
myWorkComplete = true;
if (isRecurring)
{
goto begin;
}
if (!isImmediate)
{
TimerFactory::GetInst()->TimerFired(myThread, this);
}
}
These guys are created like this:
std::function<void()> run_callback = std::bind(&Dispatcher::Run, this);
TimerFactory::GetInst()->CreateTimer(run_callback, MY_DISPATCHER_CLOCK_RATE, true, true);
And
void TimerFactory::CreateTimer(std::function<void()>theCallback, uint theInterval, bool theImmediate, bool recurring)
{
std::lock_guard<std::mutex> guard(myMutex);
if (myTerminated == true)
{
return;
}
thread* t = new thread(&TimerFactory::CreateTimerOnThread, theCallback, theInterval, theImmediate, recurring);
if (recurring)
{
t->detach();
}
else if (theImmediate)
{
t->join();
}
else
{
myThreads.push_back(t);
}
}
Followed by:
void TimerFactory::CreateTimerOnThread(std::function<void()>theCallback, uint theTimer, bool theImmediate, bool recurring)
{
if (theImmediate)
{
Timer p(theCallback, theTimer, std::this_thread::get_id(), theImmediate, recurring);
p.Start();
}
else
{
Timer* p = new (std::nothrow) Timer(theCallback, theTimer, std::this_thread::get_id(), theImmediate, recurring);
Dispatcher<Timer>::GetInst()->addElement(p);
}
}
The Timer objects that are !isImmediate are the ones that are causing the problem when I pop them off of a list:
template <typename T>
class Dispatcher
{
private:
static Dispatcher<T>* myInstance;
static std::once_flag myOnceFlag;
std::list<T*> myData;
std::mutex myMutex;
Dispatcher()
{
myInstance = this;
}
public:
static Dispatcher* GetInst()
{
std::call_once(Dispatcher::myOnceFlag, []() {new Dispatcher(); });
return Dispatcher::myInstance;
}
virtual void Initialize()
{
//std::lock_guard<std::mutex> guard(myMutex);
while (myData.size() > 0)
{
myData.pop_back();
}
std::function<void()> run_callback = std::bind(&Dispatcher::Run, this);
TimerFactory::GetInst()->CreateTimer(run_callback, MY_DISPATCHER_CLOCK_RATE, true, true);
}
/* Add an element to my list */
bool addElement(T* theElement)
{
std::lock_guard<std::mutex> guard(myMutex);
myData.push_back(theElement);
return true;
}
/* Clear my list */
void Reset()
{
std::lock_guard<std::mutex> guard(myMutex);
while (myData.size() > 0)
{
myData.pop_back();
T* temp = (*myData.begin());
myData.pop_front();
temp->Start();
delete temp; // This causes the exception.
}
}
virtual void Run()
{
std::lock_guard<std::mutex> guard(myMutex);
if (myData.size() > 0)
{
T* temp = (*myData.begin());
myData.pop_front();
temp->Start();
delete temp; // This is the line that leads to the exception.
}
}
};
I'm trying to wrap them in unique_ptrs but when the destructor gets called my application throws the exception:
Exception thrown at 0x0F695DCF (SudokuAPI.dll) in SudokuInterface.exe: 0xC0000005: Access violation reading location 0xDDDDDDDD. occurred
and the call stack is:
SudokuAPI.dll!std::_Func_class<void>::_Tidy() Line 470 C++ Symbols loaded.
SudokuAPI.dll!std::_Func_class<void>::~_Func_class<void>() Line 356 C++ Symbols loaded.
SudokuAPI.dll!std::function<void __cdecl(void)>::~function<void __cdecl(void)>() Line 53 C++ Symbols loaded.
SudokuAPI.dll!Timer::~Timer() Line 35 C++ Symbols loaded.
SudokuAPI.dll!Timer::`scalar deleting destructor'(unsigned int) C++ Non-user code. Symbols loaded.
This exception also occurs when not using unique_ptrs, so I'm stuck. Any thoughts would be greatly appreciated.
When a Timer starts with isRecurring = true, the thread it runs on never ends. Trying to destroy the Timer leads to undefined behaviour, as you have a running function where this is an invalid pointer

Builder design pattern does not work for me

I have a problem with a c++ code I just written. The code is a sample of the Builder design pattern. I created an abstract builder class, and two classes inherited from this class: MonsterBuilder and RuffianBuilder. I created a Builder class, this class receives a Monster or a RuffianBuilder, and constructs a new instance of these classes. The problem comes here: if the MonsterBuilder class is used to build a new instance the program terminates with an error (a.exe has stopped working). If the Builder receives a RuffianBuilder, it constructs a new instance without an error. Here is the sample code:
#include <iostream>
class Character
{
private:
// Attributes
int dex;
int str;
int end;
// skills
int lockpick;
int guns;
int sneak;
/***************************************** Setters ********************************************************/
// Attribute setters
public:
void setStrength(const int &s)
{
this->str = s;
}
void setDexterity(const int &d)
{
this->dex = d;
}
void setEndurance(const int &e)
{
this->str = e;
}
// Skill setters
void setLockpick(const int &s)
{
this->lockpick = s;
}
void setSneak(const int &s)
{
this->sneak = s;
}
void setGuns(const int &s)
{
this->guns = s;
}
int getGuns()
{
return this->guns;
}
int getStrength()
{
return this->str;
}
};
/* Abstract builder */
class CharacterBuilder
{
protected:
Character * int_character;
public:
Character * getCharacter()
{
return int_character;
}
void buildCharacter()
{
int_character = new Character;
}
virtual void buildSkills() = 0;
virtual void buildAttributes() = 0;
};
class MonsterBuilder : public CharacterBuilder
{
public:
virtual void buildSkills()
{
int_character->setLockpick(10);
int_character->setSneak(12);
int_character->setGuns(50);
}
virtual void buildAttributes()
{
int_character->setStrength(5);
int_character->setDexterity(5);
int_character->setEndurance(5);
}
};
class RuffianBuilder : public CharacterBuilder
{
public:
virtual void buildSkills()
{
int_character->setLockpick(10);
int_character->setSneak(12);
int_character->setGuns(50);
}
virtual void buildAttributes()
{
int_character->setStrength(5);
int_character->setDexterity(5);
int_character->setEndurance(5);
}
};
class Builder
{
public:
void setBuilder(CharacterBuilder * builder)
{
this->builder = builder;
}
Character * getCharacter()
{
return builder->getCharacter();
}
void buildCharacter()
{
//std::cout << builder->buildSkills;
builder->buildSkills();
builder->buildAttributes();
}
private:
CharacterBuilder * builder;
};
int main()
{
Builder B;
RuffianBuilder R;
MonsterBuilder Mo;
B.setBuilder(&R);
B.buildCharacter();
std::cout << B.getCharacter()->getGuns();
std::cout << B.getCharacter()->getStrength();
B.setBuilder(&Mo);
B.buildCharacter();
//std::cout << B.getCharacter()->getStrength();
return 0;
}
What causes this problem? Could somebody explain it?
Reading uninitlalized variable will cause undefined behavior.
I added builder->buildCharacter(); to Builder::buildCharacter() and then this code seems working well.
class Builder
{
public:
void setBuilder(CharacterBuilder * builder)
{
this->builder = builder;
}
Character * getCharacter()
{
return builder->getCharacter();
}
void buildCharacter()
{
//std::cout << builder->buildSkills;
builder->buildCharacter(); // add this line
builder->buildSkills();
builder->buildAttributes();
}
private:
CharacterBuilder * builder;
};

How to properly override virtual method to add functionality?

In base class I have simple remove by id virtual function, however in derived class I need also emit a signal (notify) after removing.
In base class. Below is the default implementation of function
void Ui::GameEntityList::remove_games_by_sport_id_virt(const QString &sport_id)
{
for(QList<GameEntity*>::iterator it = m_game_list.begin();
it != m_game_list.end();)
{
GameEntity* tmp = (*it);
if(tmp->get_sport_id() == sport_id)
{
it = m_game_list.erase(it);
delete tmp;
tmp = 0;
}
else
{
++it;
}
}
}
In derived class. Overriding
void Ui::GameWidgetList::remove_games_by_sport_id_virt(const QString &id)
{
QList<GameEntity*>::iterator it;
for(it = m_game_list.begin(); it != m_game_list.end();)
{
GameWidget* tmp = dynamic_cast<GameWidget*>(*it);
Q_ASSERT(tmp != NULL);
if(tmp->get_sport_id() == id)
{
it = m_game_list.erase(it);
emit remove_game_in_monitor(tmp->get_id(), this->get_monitor_number()); // need to emit this signal
delete tmp;
tmp = 0;
}
else
{
++it;
}
}
this->set_number_of_games(m_game_list.size()); // need to call this function
}
I can't manage a way to avoid code duplication. Should I have an empty virtual notify() function and call it after removing an element? That way I can override notify() in derived to do the job. Is that an acceptable decision? Is implementing remove by id in base class unnecessary?
In your case, it is not that bad regarding amount of duplicated code. But, anyway, in situations like this, you may want to make this function non-virtual and move this customizable functionality to other virtual functions:
class GameEntityList
{
private:
virtual void on_erase(GameWidget* w)
{
//empty
}
virtual void on_finish(GameWidget* w)
{
//empty
}
//others
};
class GameWidgetList : public GameEntityList
{
private:
virtual void on_erase(GameWidget* w)
{
remove_game_in_monitor(w->get_id(), this->get_monitor_number());
}
virtual void on_finish(GameWidget* w)
{
this->set_number_of_games(m_game_list.size());
}
//others
};
And then:
void Ui::GameEntityList::remove_games_by_sport_id_virt(const QString &id)
{
QList<GameEntity*>::iterator it;
for(it = m_game_list.begin(); it != m_game_list.end();)
{
if(tmp->get_sport_id() == id)
{
it = m_game_list.erase(it);
this->on_erase(tmp); //customizable
delete tmp;
tmp = 0;
}
else
{
++it;
}
}
this->on_finish(); //customizable
}

Why this Node List doesen't work correct?

Why, although I have add 4 GameObjects, in the GameLoop the Console give only one times "GameObject Update" and "GameObject Render" out ?
And another Qustion, how I can made a Self Destroy Function for the GameObjects?
And the last Question, whats the best methode, that a GameObject can communicate with other game objects in the list?
#include <iostream>
using namespace std;
class GameObject
{
public:
GameObject *nextGameObject;
GameObject()
{
cout<<"GameObject Constructor!\n";
nextGameObject = nullptr;
}
~GameObject()
{
cout<<"GameObject Destructor\n";
if(nextGameObject != nullptr)
{
delete nextGameObject;
}
}
virtual void Update()
{
cout<<"GameObject Update!\n";
}
virtual void Render()
{
cout<<"GameObject Render!\n";
}
};
class GameObjectManager
{
private:
GameObject *firstGameObject;
public:
GameObjectManager()
{
firstGameObject = nullptr;
}
~GameObjectManager()
{
if(firstGameObject != nullptr)
{
delete firstGameObject;
}
}
void Update()
{
if(firstGameObject != nullptr)
{
GameObject *helpGameObject = firstGameObject;
while(helpGameObject != nullptr)
{
helpGameObject->Update();
helpGameObject = helpGameObject->nextGameObject;
}
}
}
void Render()
{
if(firstGameObject != nullptr)
{
GameObject *helpGameObject = firstGameObject;
while(helpGameObject != nullptr)
{
helpGameObject->Render();
helpGameObject = helpGameObject->nextGameObject;
}
}
}
void Add(GameObject *newGameObject)
{
if(firstGameObject == nullptr)
{
firstGameObject = newGameObject;
}
else
{
GameObject *helpGameObject = firstGameObject;
while(helpGameObject != nullptr)
{
helpGameObject = helpGameObject->nextGameObject;
}
helpGameObject = newGameObject;
}
}
};
int main()
{
GameObjectManager gom;
bool run = true;
gom.Add(new GameObject);
gom.Add(new GameObject);
gom.Add(new GameObject);
gom.Add(new GameObject);
while(run)
{
cout<<"GameLoop Start\n";
gom.Update();
gom.Render();
cout<<"GameLoop End\n";
cin.get();
}
return 0;
}
This is a horrible solution for a linked list, but I'll answer your question. The fault is in Add(). Here, you just modify the local variable helpGameObject. Instead you should stop at the object that has no successor and modify that objects nextGameObject.
The problem is in your Add function.
the follwing line:
helpGameObject = newGameObject;
doesn't actually change the value pointed to by helpGameObject, rather it changes the pointer itself.
I think the best solution is to change it to the following
GameObject *helpGameObject = firstGameObject;
while(helpGameObject->nextGameObject != nullptr)
{
helpGameObject = helpGameObject->nextGameObject;
}
helpGameObject->nextGameObject = newGameObject;