1

I am doing a project on OOPs in C++ and getting some errors (Segmentation Fault).

sObjects is a static vector containing pointers to every object created in the Base class.

I have also checked the addresses by uncommenting the lines : // cout<<(*it)<<endl; // cout<<this<<endl; .They are same.

So why I am getting garbage values/segmentation fault ? Do I have to do some sort of casting?

Here is my code:

//main.cpp
#include <iostream>
#include "Base.h"
using namespace std;


int main()
{

    Base::UnitTest();

    vector<Base *>::iterator it;
    for (it = Base::sObjects.begin(); it < Base::sObjects.end(); ++it)
    {
        // cout<<(*it)<<endl;
        cout<<(*(*it))<<endl;
    }

    return 0;
}
//Base.h
#ifndef BASE_H
#define BASE_H

#include <iostream>
#include <vector>
using namespace std;

struct Node{
    int val;
};

class Base
{
private:
    Node node_;
public:
    Base(int a=0);
    ~Base();

    static vector<Base*> sObjects;
    friend ostream &operator<<(ostream &os, const Base &myObj);

    static void UnitTest();
};

#endif
//Base.cpp
#include "Base.h"
vector<Base*> Base::sObjects;

Base::Base(int a)
{
    this->node_.val=a;
    sObjects.push_back(this);
    // cout<<this<<endl;
}

Base::~Base()
{
}

ostream &operator<<(ostream &os, const Base &myObj)
{
    os<<myObj.node_.val;
    return os;
}

void Base::UnitTest()
{
    Base obj(23);
}
Aryan Agarwal
  • 23
  • 2
  • 5
  • You are not externing ```sObjects```. How is this even compiling? – user2233706 Mar 07 '21 at 15:04
  • I am creating a sample object of base class in the UnitTest of Base class with value 23, but the values printing in terminal are garbage. – Aryan Agarwal Mar 07 '21 at 15:06
  • The object created in `Base::UnitTest()` goes out of scope however you keep its pointer in your vector after it no longer exists. This is an instance of a dangling pointer. This is undefined behavior / anything can happen including it appearing to work some of the time. Thankfully you found that it does not work in your case. It would have been much worse if it appeared to work even though it was broken. – drescherjm Mar 07 '21 at 15:08
  • @user2233706 It's compiling without any error. Just the values printed are garbage – Aryan Agarwal Mar 07 '21 at 15:08
  • The values printed are garbage because the vector has a dangling pointer after the object pointed to is destructed. – Eljay Mar 07 '21 at 15:37

2 Answers2

1

The object created in Base::UnitTest() goes out of scope however you keep its pointer to it using sObjects.push_back(this); in your vector after it no longer exists. This is an instance of a dangling pointer. This is undefined behavior. Anything can happen including it appearing to work some of the time. Thankfully you found that it does not work in your case. It would have been much worse if it appeared to work even though it was broken.

Related: What is a dangling pointer?

Also: What are all the common undefined behaviours that a C++ programmer should know about?

In the also link this is a case of using a pointer who's lifetime has ended. Using pointers to objects whose lifetime has ended (for instance, stack allocated objects or deleted objects)

drescherjm
  • 10,365
  • 5
  • 44
  • 64
0

The object is created in the scope of Base::UnitTest(). So you are saving the pointer the memory in the function stack call of Base::UnitTest() in Base::sObjects. To avoid this behaviour you may remove the pointer from Base::sObjects when the objects no longer exists. i.e., you may remove during the destrction of the object (in destructor).

j-tesla
  • 67
  • 2
  • 7