1

I have a class, that contains a struct. I have a method on the class that creates a new object of this struct, return it as a pointer.

I have another method in this class that takes a pointer to this struct and prints out it's data.

Only problem is, some weird text shows up in the console when I try to print it out.

Code example (not actual code, but the principle of it):

// Header

class TestClass
{
    public:

        struct TestStruct
        {
            int ID;
            string Name;
        };

        TestClass::TestStruct* CreateStruct(string name, int id);
        void PrintStruct(TestClass:TestStruct* testStruct);
}

// C++ File

TestClass::TestStruct* TestClass::CreateStruct(string name, int id)
{

    TestStruct testStruct;

    testStruct.ID = id;
    testStruct.Name = name;

    TestClass::TestStruct *pStruct = &testStruct;

    return pStruct;

};

void TestClass::PrintStruct(TestClass::TestStruct* testStruct)
{

    cout << (testStruct)->ID << "\n";
    cout << (testStruct)->Name << "\n";

};

int Main()
{

    TestClass tClass;

    tClass.PrintStruct(tClass.CreateStruct("A name", 1));

}
Deukalion
  • 2,516
  • 9
  • 32
  • 50

1 Answers1

3

You're returning a pointer to a local variable, and running into undefined behavior.

TestClass::TestStruct* TestClass::CreateStruct(string name, int id)
{
    TestStruct testStruct;
    //...
    TestClass::TestStruct *pStruct = &testStruct;
    return pStruct;
}   //testStruct is destroyed here
    //the pointer pStruct is invalid

To get this to work, you can either return a smart pointer or allocate the memory dynamically to extend the lifetime of the object. Remember that you have to delete it explicitly:

TestClass::TestStruct* TestClass::CreateStruct(string name, int id)
{

    TestStruct* testStruct = new TestStruct;

    testStruct->ID = id;
    testStruct->Name = name;

    return testStruct;

};

Also, seriously think about whether you actually need pointers. Prefer automatic variables when possible. If I were you, I'd do:

TestClass::TestStruct TestClass::CreateStruct(string name, int id)
{

    TestStruct testStruct;
    testStruct.ID = id;
    testStruct.Name = name;
    return testStruct;
};

void TestClass::PrintStruct(const TestClass::TestStruct& testStruct) const
{
    cout << testStruct.ID << "\n";
    cout << testStruct.Name << "\n";
};
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • The second example worked, I just figured it out earlier that it probably had something to do with the object not existing anymore. How do I later delete it explicitly? – Deukalion Jun 22 '12 at 07:35
  • @Deukalion just `delete` the pointer that gets returned when you no longer need it. – Luchian Grigore Jun 22 '12 at 07:37