🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Avoid referencing stack objects?

Started by
1 comment, last by mrjones 16 years, 11 months ago
I have registered both referencing and releasing for String class. The memory manager that handles references is keeps the references separately such that the actual objects are not aware of the reference and release mechanism. There are no memory leaks for constructed and factory made strings, but addition of strings causes memory leak. My + operator returns a string from stack, but AngelScript attempts to release its reference, but since it is from stack, it should be ignored completely. Is it somehow possible to avoid AngelScript trying to manage external pointers or should I handle it in my own memory manager by wrapping operators in separate functions and completely ignoring the pointers they return by setting the reference value to at least 2? I wouldn't want to use the same method as in the example, where reference counter is included inside the object, because I have quite many classes and it is difficult to manage them this way. The code is below, perhaps it makes more sense than my fuzzy explanation:

AngelMemoryManager<DATA::String*> AngelString::memoryManager; // Strings memory manager

String* AngelString::reference(DATA::String* str) {
  return memoryManager.reference(str); // registers the pointer and increments the value (if pointer is new, the reference is 1)
}

void AngelString::release(DATA::String* str) {
  memoryManager.release(str); // releases the pointer and decrements the value (if value is 0, the pointer is deleted)
}

// This is the string factory that creates new strings for the script
String* AngelString::factory(asUINT length, const char *s) {
  return reference(NEW(String(s, length)));
}

// This is a wrapper for the default AngelString constructor, since
// it is not possible to take the address of the constructor directly
void AngelString::construct(String* thisPointer) {
  reference(PLACEMENT_NEW(thisPointer, String()));
}

String operator + (const String& string1, const String& string2); // the declaration of addition operator 

// Current operator registration
	r = engine->RegisterObjectBehaviour("String", asBEHAVE_ADDREF,
                                      "void f()", asFUNCTION(AngelString::reference),
                                      asCALL_CDECL_OBJLAST); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("String", asBEHAVE_RELEASE,
                                      "void f()", asFUNCTION(AngelString::release),
                                      asCALL_CDECL_OBJLAST); assert( r >= 0 );

	r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "String f(const String ∈, const String ∈)",
                                      asFUNCTIONPR(operator +,
                                                  (const String &, const String &),
                                                  String),
                                      asCALL_CDECL); assert( r >= 0 );
Thanks a lot to anybody who has a good idea for solving this problem.
Advertisement
If you're mixing memory management like this you're going to have problems, reference counting and stack allocated objects don't work well together. In C++ you're ok because you manually decide when an object is reference counted or stack allocated, but in AngelScript you don't have that option.

You're telling AngelScript that the string type is memory managed through reference counting, but you're still returning the string value on the stack. The string on the stack should be destroyed directly by calling the destructor, but AngelScript has no way of knowing that. Also, what if the script decides to store a reference to the string somewhere, in that case the memory on the stack must not be destroyed.

Actually, AngelScript should probably give an error when you try to register your operator that returns the string by value, since it will never work.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Thanks a lot. That's exactly what I wanted to know. I'll just always return new objects to AngelScript in that case or let the my memory manager ignore the externally managed pointers specifically.

[Edited by - mrjones on July 27, 2007 3:52:12 AM]

This topic is closed to new replies.

Advertisement