ImStudio icon indicating copy to clipboard operation
ImStudio copied to clipboard

BaseObject's parent pointer variable not initialized?

Open sigmareaver opened this issue 3 years ago • 3 comments

I'm working on a serializer for ImStudio so that I can save and load GUI projects (using yaml-cpp).

Admittedly, I'm not super familiar with how ImStudio stores and looks up children/parents, or rather, how the object hierarchy works, at the moment.

I wrote something like this pseudo code:

    if (obj.parent)
        out << "ParentID" << obj.parent->id;
    else
        out << "ParentID" << 0;

I then tested this serialization with a few widgets (no nesting) in a window, and the objects' parent ID always serialize as: ParentID: 30198988 (This turns out to be 0x01CCCCCC, probably some kind of magic number.) I tried adding the line parent = nullptr; to BaseObject's constructor, but this doesn't seem to make a difference. And also, when I put in a break point and look at the object that is currently being serialized, the obj.parent doesn't appear to be valid memory.

I was hoping you might be able to see if you have similar results with your object.parent, or if it's just something I did.

Also, I did notice that in the Object constructor, it seems to set itself as the parent of itself, so I'm thinking I may be misunderstanding your data structure, and it isn't tree-like?

sigmareaver avatar Oct 02 '22 00:10 sigmareaver

I think I found the issue.

if (!current_child)
    {
        Object widget(idvar, type_);
        objects.push_back(widget);
    }

Here in ims_buffer.cpp you construct a stack allocated Object, and then copy it into a std::vector. This basically invalidates the Object* parent pointer, because it's pointing to the stack allocated object that will soon be destroyed.

Now, I actually thought you could do something like this instead:

if (!current_child)
    {
        objects.emplace_back(std::move(Object(idvar, type_)));
    }

But it turns out that this doesn't fix the problem. Unless you happen to have a solution in mind, the only other way I know of to fix this is to turn std::vector<Object> objects into this instead: std::vector<Object*> objects and just deal with the manual memory management.

Edit: Someone brought to my attention that std::unique_ptr could also be used to alleviate the need to manage memory by hand. Like so:

std::vector<std::unique_ptr<Object>> objects; 
auto widget = std::make_unique<Object>(idvar, type_);
objects.push_back(std::move(widget));

sigmareaver avatar Oct 02 '22 01:10 sigmareaver

See https://github.com/Raais/ImStudio/commit/ac16cd858ef7d5f2575bd27286e7935171b48f1e for the solution I went with.

sigmareaver avatar Oct 02 '22 15:10 sigmareaver

Hi,

I believe all the pointers were already removed altogether in 6bf1ed0. If it's at all possible I would recommend merging with that commit. It removes a LOT of my convoluted code and other messy stuff, + better explanation comments. (or even later 323b441)

Otherwise let me know if you need any help even with the older commits. I might have to go through them a bit though.

Raais avatar Oct 02 '22 17:10 Raais