0 votes

Hello everyone,
I'm trying to delete an object, that I only have a reference to. To be a bit more specific, I am calling free() from inside an object, that holds an array of the objects I'm trying to delete.
Here is what the code looks like (I don't know what else to show).

agent_body.queue_free()

The error message is just tells me:

Attempted to free a reference.

Thus I'm not sure if I should just make a method like kill() in the object I'm trying to delete that just executes:

self.queue_free()

and then call:

agent_body.kill()

Alternatively I tried to figure out if it is possible to get the object instance itself from the Reference() object, but I couldn't find anything relevant there.
So should I go for the kill() method approach, or is there something better that I don't know about?

in Engine by (14 points)

1 Answer

+3 votes

Objects inheriting Reference must not be freed explicitely. They get destroyed only once nothing else references them. If you have an array of references, simply setting the item to null will free it, if it's the only place it is referenced.

You say you want to use free() from inside the object itself, however I can only tell you this is a bad design. It can have really nasty consequences.

In order to use free(), your script must inherit Object (or a class based on Object which doesn't inherit Reference). But be careful about this, because it destroys the object right now. Any piece of code following the line with free() may potentially crash the game, because the object will be gone.

The most common pattern where an object "kills itself" is in the case of nodes, using the queue_free() function.
Indeed, objects inheriting Node don't inherit Reference. So they are not ref-counted, and freeing them immediately frees them. However, because doing this immediately can lead your code to step over itself and crash, queue_free() is preferred so that the actual destruction happens during idle time, when scripts are done running.

If your object is also referenced inside an array somewhere, you may want to emit a signal so that the holder of the array removes the object from it. Or better, delegate destruction to this holder, so you won't need signaling.

by (27,902 points)

Hi, thank you very much for this detailed answer. I'm sorry I didn't respond earlier, I kind of ignored this issue during the last week as I was squashing a lot of bugs in my code.

I basically made the mistake of writing a bunch of classes, not being concerned about how they are going to be placed into the scene tree.
Long story short, I totally circumvented this issue by working directly with nodes instead of classes.
The holder now simply calls queue_free() on the Node once it has everything it needs from it.

Best of wishes, Paul

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.