-2

Below is a simple markup of a program layout I can currently using. Its for OpenGL. Essentially I want to initialize the mesh before I ship it to the main loop. I can do this with

vector<Mesh> MeshContainer;

And once I initialize it, push it in the MeshContainer and then call it in the main loop like that. I would much rather be able to define a pointer in the Program struct, create the mesh in the init() function, and then store the pointer and then use the pointer.

#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;

struct Mesh {

    vector<float> MeshVector;

};

struct Program {

    bool shouldClose = false;
    // Store the mesh as a pointer after we do some initialization.
    Mesh *mp;

    // Initialize is ran before the program and initializes before the loop begins.
    void init() {

        // Create the sudo-mesh.
        Mesh myMesh;

        // Give it some values. 9 in total.
        myMesh.MeshVector = {
            1.0f, -1.0f, 1.0f,
            -1.0f, 1.0f, -1.0f,
            1.0f, -1.0f, 1.0f,
        };

        mp = &myMesh;

    }

    // This is ran in the loop.
    void run() {
        cout << mp->MeshVector[0] << endl;
    }

    void loop() {

        // Simulates layout of OpenGL application.
        init();

        // Program loop.
        while (!shouldClose) {
            // This simulates the draw loop.
            run();
        }
    }

};

int main() {

    // Create the program.
    Program app;
    app.loop();

    return 0;
}

However, even in this simple application I wrote up, it gives me "vector subscript is out of range". Now it is pretty pointless (pun intended) to do this because I'll eventually write up a memory management class to bypass all this hoopla, but while I learn, I'd like this to be my quick and dirty solution.

What exactly am I doing wrong here? Should I be able to simply do:

cout << mp->MeshVector[0] << endl;

And get the result expected?

Edit:

My question does not involve a function returning a pointer. It simply looks to set a property of the struct to the pointer of some object I created in that method. Nothing is being returned.

  • The question I asked may resemble what may be a duplicate to the question https://stackoverflow.com/questions/25797769/returning-pointer-to-local-variable however one important note that my code does not return anything, I am simply defining an object in a function, and then pointing to it in a public pointer in a struct. No function written in my question and example does this. – Christopher 'Solidus' DeJong Sep 08 '17 at 21:05

1 Answers1

1

The line

Mesh myMesh;

creates a local variable in init() and

mp = &myMesh;

creates a pointer to that local variable. However, this local variable does not exist anymore when you leave init(). Hence, accessing it results in undefined behavior.

The simple solution is to declare myMesh as a member variable of Program or to instantiate it on the heap with Mesh* myMesh = new Mesh() (and destroy it when you shut down).

Nico Schertler
  • 32,049
  • 4
  • 39
  • 70
  • I remember why I didn't do that in the first place, fixed that problem, and then avoided trying it afterwards. My mistake. – Christopher 'Solidus' DeJong Sep 08 '17 at 20:46
  • Go with the member variable if you can. The `new` approach adds a lot of complexity. But if you must, [`std::unique_ptr`](http://en.cppreference.com/w/cpp/memory/unique_ptr) and [`std::make_unique`](http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique) are also worth checking out. They automate the memory management and protect you from the [Rule of Three](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – user4581301 Sep 08 '17 at 20:48
  • Yes, a member variable will most certainly help me for now. Later down the road I won't be needing to do this as OpenGL VBO ID is the only reference I need post-initialization. Thanks. – Christopher 'Solidus' DeJong Sep 08 '17 at 21:07