Reputation: 315
To give a simple example of the problem I am having, consider a class that creates a link(like in a chain). Each link has a parent link except for the root link. The parent link of the root link is null.
#ifndef LINK_HPP
#define LINK_HPP
#include <memory>
#include <string>
//Link.hpp
class Link
{
public:
Link(const std::string &linkName, const Link *parentLink);
Link(const std::string &linkName);
const Link* getParentLink();
~Link();
static Link* createRootLink(const std::string &linkName);
static Link* getRootLink();
private:
std::string linkName;
const Link *parentLink;
};
#endif
#include "Link.hpp"
Link* Link::createRootLink(const std::string &linkName)
{
std::unique_ptr<Link> rootLink(new Link(linkName));
return rootLink.get();
}
Link::Link(const std::string &linkName)
{
this->linkName = linkName;
this->parentLink = nullptr;
}
Link::Link(const std::string &linkName, const Link* parentLink)
{
this->linkName = linkName;
this->parentLink = parentLink;
}
Link::~Link()
{
}
const Link* Link::getParentLink()
{
return this->parentLink;
}
In unit testing my code, I have created a helper class which defines functions useful for the testing. In HelperClass.hpp there is a static method that creates a shared pointer to a link and returns the raw pointer. Keep in mind this helper function is merely to reproduce a problem. I understand the method is kinda useless.
#include "Link.hpp"
class HelperClass
{
public:
static Link* createALink(const std::string &linkName, Link* parentLink)
{
std::shared_ptr<Link> link(new Link(linkName, parentLink));
return link.get();
}
};
Alright now for the actual test that shows where the problem is.
#include "gtest/gtest.h"
#include "Link.hpp"
#include "HelperClass.hpp"
class ReferenceFrameTest : public ::testing::Test
{
protected:
virtual void SetUp()
{
}
virtual void TearDown()
{
}
Link* rootLink = Link::createRootLink("root");
// Why does this call right here change the parentLink of rootLink!!
Link* link1 = HelperClass::createALink("link1", rootLink);
private:
};
TEST_F(ReferenceFrameTest, testRootLinkHasNullParent)
{
// the parent link of rootLink should be nullptr or 0
// this currently outputs 0x264f960
std::cout << rootLink->getParentLink() << std::endl;
// This fails if I create the Link* from HelperClass.hpp
ASSERT_FALSE(rootLink->getParentLink());
}
The act of creating the pointer to a Link in HelperClass
somehow is changing the parentLink
of rootLink
. Note that if instead I just instantiate a new Link on the stack, the parentLink
of rootLink
remains nullptr
as it should. What am I missing here? Thanks so much in advance for the help!
Upvotes: 1
Views: 37
Reputation: 72431
createRootLink
returns a dangling pointer.
Link* Link::createRootLink(const std::string &linkName)
{
std::unique_ptr<Link> rootLink(new Link(linkName));
return rootLink.get();
}
The unique_ptr
deletes its object when it goes out of scope, which is at the end of the createRootLink
function. So that memory can be reused, or all sorts of other undefined behavior.
Upvotes: 1