I've been looking for documentation for cocos2d-x but it seems to be really really poor beyond the very basics. I understand that my own classes should inherit from CCObject to be able to use (originally cocoa's) retain/release mechanism, but I'm still confused about what happens when you new something. init is not called automatically. is it OK to call it from inside the constructor? does that alone guarantee that my object will start with a reference count of 1? what is CC_SAFE_DELETE and when should I use it? do release and autorelease work exactly like in cocoa? what about CC_SYNTHESIZE? I just need to see a properly coded class example (and it's instantiation/destruction) to understand what I'm supposed to do so as not to screw and leave memory leaks.
thank you.
If you will look to the code of CCObject class, you will see that in it's constructor reference count is set to 1 there. So, object creation with new is correct. Init is not called because CCObject class has no such a method. Usually I prefer to create objects using static constructor. Smth like
MyClass* MyClass::createInstance()
{
MyClass* object = new MyClass();
// you can create virtual init method
// and call it here
if( initWasSuccessful )
{
object->autorelease();
}
else
{
CC_SAFE_RELEASE_NULL(object);
}
return object;
}
About all macroses like CC_SAFE_DELETE - you can find them in the code of cocos2dx. This macros just check if object is NULL to prevent crash on trying to call release method.
The answer provided by Morion is great, I'd just like to add a few useful links about this matter.
Here you can find the official memory management in Cocos2d-x page:
Memory Management in Cocos2d-x
This forum page also contains some more details and clarifications about it:
Memory deallocation in Cocos2d-x
Enjoy coding!
Related
I've taken over some legacy C++ code (written in C++03) which is for an application that runs on an RTOS. While browsing the codebase, I came across a construct like this:
...
new UserDebug(); ///<User debug commands.
...
Where the allocation done using new isn't stored anywhere so I looked a bit deeper and found this
class UserDebug
{
public:
///Constructor
UserDebug()
{
new AdvancedDebug();
new CameraCommand();
new CameraSOG();
new DebugCommandTest();
new DebugCommand();
// 30 more new objects like this
};
virtual ~UserDebug(){};
};
I dug deeper into each of the class definitions and implementations mentioned and couldn't find any reference to delete anywhere.
This code was written by the principal software engineer (who has left our company).
Can anyone shed some ideas on why you would want to do something like this and how does it work?
Thanks
If you look into the constructors of those classes you’ll see that they have interesting side effects, either registering themselves with some manager class or storing themselves in static/global pointer variables á la singletons.
I don’t like that they’ve chosen to do things that way - it violates the Principle of Least Surprise - but it isn’t really a problem. The memory for the objects is probably (but not necessarily) leaked, but they’re probably meant to exist for the lifetime of the executable so no big deal.
(It’s also possible that they have custom operator news which do something even odder, like constructing into preallocated static/global storage, though that’s only somewhat relevant to the ‘why’.)
If these objects created once they might be expected to have the lifetime of the application (similar to singletons) and thus should never be deleted.
Another way to capture pointer is through overloaded operator new: both global and class specific. Check if there are any overloads that implement some sort of garbage collection.
Hello I want to know what all I should take care about for memory leak in cocos2d-x. I am taking care of all the objects created by me i.e. using core C++ but how to take care or manage the code in cocos2d-x to avoid memory leak ?
What about actions,sprites and all ? Please give me reason also so it will be better for me to understand
Thanks
try to use the cocos2d-x static function instead of new CLASS_NAME(), since all the static create function is autorelease() and you don't need to take care of it.
if you are not sure what you are doing, make sure every instance is a subclass of CCObject, and whenever when you call a new Class(), remember to call release().
This resource describes a method of creating a modeless dialog using pointers. They create a pointer that pointer to the dialog class and then use the -> syntax.
CModeLess *m_pmodeless = new CModeLess(this);
m_pmodeless->Create(CModeLess::IDD);
m_pmodeless->ShowWindow(SW_SHOW);
I have been doing something like this so far:
CModeLess m_pmodeless;
m_pmodeless.Create(IDD_DIALOG);
m_pmodeless.ShowWindow(SW_SHOW);
I do this mainly because I feel comfortable using classes. Is there any disadvantage of using this approach?
Secondly, in the pointer approach I have to do something like this to close the window: (if I am not mistaken)
if(m_pmodeless != NULL) { delete m_pmodeless; }
Is there some deletion I have to do If I use classes or is m_pmodeless.closeWindow() enough?
I apologize if this is a very basic question, but i'm curious to know.
This is a tricky question to answer, as a lot depends on exactly what you are trying to do and also on exactly how CModeless is implemented. In general you are right to avoid pointers, but GUI programming has special issues because the C++ objects in your program represent GUI objects on the screen, and coordinating the destruction of the C++ objects in your program with the GUI objects on the screen can be quite tricky. Sometimes pointers are the simplest answer to this problem.
I'm assuming that m_pmodeless is a member variable of another class.
One issue is the lifetime of the objects. In the class version the CModeless object will be destroyed when the containing object is destroyed. Whether that's OK for you depends on your code. Whether that also destroys the modeless dialog depends on how CModeless is implemented. You need to look at the CModeless destructor if you can, or the documentation for CModeless if you can't. With the pointer version you have explicit control over when the object is destroyed, just call delete at the right time.
Another issue is that some GUI libraries automatically delete the C++ object when the GUI object is destroyed. Something like this (on Windows)
case WM_NCDESTROY:
...
// last message received so delete the object
delete this;
break;
Code like this is assuming that all your objects are heap allocated and automatically deleting them for you at the right time. If CModeless is written like this then you have no choice but to use the pointer version.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
When to use “new” and when not to, in C++?
When should I use the new keyword in C++?
It seems like I could program something without ever using the word new, and I would never have to worry about deleting anything either, so why should I ever call it?
From what I understand, it's because I would run out of stack memory.
Is this correct? I guess my main question is, when should I call new?
It's a matter of object lifetime: if you stack-allocate your objects, the objects destructors will be called when these objects go out of scope (say, at the end of the method). This means that if you pass these objects out of the method that created them, you'll find yourself with pointers to memory that could be overwritten at any time.
It's because you may not know at compile time whether you need an object, or how many, or of what type. The new operator allows you to dynamically allocate objects without having to know such things in advance.
Here's an example of not knowing the type of object in advance:
class Account { ... };
class CheckingAccount : public Account { ... };
class VisaAccount : public Account { ... };
...
Account *acct = type == "checking" ? new CheckingAccount : new VisaAccount;
The main reason you'll need to use new/delete is to get manual control the lifetime of your objects.
Other reasons are already provided by others but I think it's the more important. Using the stack, you know exatly the lifetime of your objects. But if you want an object to be destroyed only after an event occurs, then it cannot be automatically defined.
The lifetime of the data/objects created on the stack is restricted to the block. You cannot return references/pointers to it. For data to be available across functions, you can create it on the heap with new. Of course, it can be at a higher level, or even global. But you seldom know at compile time how much data/how many objects will be needed at run time.
You can write a many non-trivial programs without ever calling "new." (or thus delete).
What you wouldn't be able to do (at least without writing or using your own equivalents) is decide what type of objects or how many you want to create at run-time, so you'd be limiting yourslef.
[updated]
You can use new to create new instance of some class, or allocate memory (for array for example), like
Object o = new Object();
Before creating new instance of class Object, you cannot use it. (Unless you have static methods.)(this is just one example of usage, sometimes other objects will instantiate or destroy objects that you need/don't need)
There are many good answers here but it is difficult to explain everything about new in one reply on SO, and if you do not understand what happens when new is called then it is difficult to know when to use it. This is one of the most important areas in programming so, after reading basic information here you should study it in more detail. Here is one of possible articles where you could start your research:
http://en.wikipedia.org/wiki/New_%28C%2B%2B%29
Topics that you will have to learn in order to understand what happens when you call new, so that you then could understand when to call it (there are more probably but this is what i can think of now):
- constructors (and destructors)
- static classes and methods
...
I am writing a lib and a demo project. The project doesn't care which version of the lib I use (I can use sdl, directx or whatever I like as the gfx backend). To get the object I do
Obj *obj = libname_newDevice();
Now, should I use delete or should I do obj->deleteMe();? I ask because I am not exactly doing new so I shouldn't be doing the delete?
I have obj->create(theType); which returns a class with the Obj interface.
My real question is do I need a libname_deleteDevice(); or is obj->deleteMe() fine since I have a deleteMe in the interface?
Since you are abstracting the creation inside libname_newDevice() (which I have to say isn't a good approach), you should destroy using something like libname_destroyDevice (obj).
And as the comment from Martin suggests, it's best to put them in the constructor and destructor of a custom class, that you just need to create on stack, and the compiler will take care of the rest.
Please try to clarify your question. It's totally unclear to me.
Why do you speak of a graphical back end? Is it relevant to the question?
Are you asking how you should design your library or how you should use it?
It's good practice to have an object factory to create the object. I assume this is the role of libname_newDevice().
The library should also provide a way to delete the object (such as obj->DeleteMe() or libname_Delete(obj) ).
Don't rely on C++'s delete: caller and library might have been compiled with different version of the compiler, which would do different things regarding memory and resources allocation. It's therefore safer if your lib deletes the object it created.
I would take one step further.
If you are using a factory function to create, it may be logical to use a factory function to destroy. In addition to this to make it all nice and exetion safe wrap in in an object.
class ObjWrap
{
public:
ObjWrap()
:obj(libname_newDevice())
{}
~ObjWrap()
{ libname_deleteDevice(obj);}
private:
ObjWrap(ObjWrap const&); // Dont copy
void operator=(ObjWrap const&); // Dont copy
Obj* obj;
}; // If you want to copy then you need to extra work on ref counting
// This may need some form of smart pointer.
I think the best way would be to honor RAII and have some reference counting wrapper object (you can even use shared_ptr with a custom deallocator).
You definitely don't want to implement Obj::deleteMe(). It would have to do something like:
delete this;
while you were still inside this->deleteMe(). Follow Jaywalker's suggestion and make the destroy function take an Obj* as a parameter.