ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
is there a 100% way to avoid such leaks?
if yes, how does it work? any hints would be great
if not, how does the "not 100%" method work?
i know there are some methods to avoid this (reference counting, ...), so how they work with C/C++?
i could do a self-written malloc or free
but the most time i use "new Object()" and STL stuff like vector or string which doesnt really make it necessary to do a malloc by my own
1: any hints (not only some doc, but some code too) would be cool
2: my biggest problem will be, what if my project i'm currently working on, is getting released and some time later strange behaviour is reported (e.g. it needs much memory resource) and i don't know why?
anybody has an idea of "logging" so i can check, "ok, the most allocated object is xyz which has been allocated n times" (i would only need a hint where the leak could be)
3: i know dlopen and now i want to know if such function is available instead of the "new" keyword like this: void* instantiateObject(char *classname,...); /*... is an argument list for the constructor like a list for printf();*/
What works 100% is manually and correctly freeing allocated memory.
What also works is reference counting, if your object structures don't contain cycles. If they do contain cycles, try to break them up, make some references weak, or encapsulate the cycle in some class and break in the destructor of that class. shared_ptr from the boost library does the reference counting for you.
You may also want to override operator new and count each allocation (and possibly override operator delete--similarly for the array-operators--to see if any object is leaked). Alternatively, put the allocation counting in an allocator class.
this is what i use to track any leaks, but there seems to be a problem with including it in header files and only seems to work if include in the .cpp file. dont know why?
anyway I'm some peeps are going to say theres something wrong with this lol.
also it checks if malloc failed, but doesnt do anything about it!
example of how i use it.
main.cpp
Code:
#include <memory_check.h>
int main(int argc, char **argv)
{
//create the singleton class
Memory* memory_ptr = Memory::manager();
//create some memory
int* a = new int;
int* b = new int;
//recover a
delete a;
//delete the manager
delete memory_ptr;
return 0;
}
this should create a memory leak file with the line and file of the new call.
First, a 100% way of preventing memory leak would be equivalent to the halting problem. (ie. Provably impossible)
Secondly the best design principle is to consider carefully who sould own and be responsible for the allocation and deallocation of the data. The Law of Demeter can be a guide in deciding this, so can the notion of object lifetimes. (ie. The owner must live as least as long as any user of the data)
I'm not sure exactly what you are after. You said some documentation or some code would be cool.
I have here some code for automatic reference counting in c++, that works for objects that inherit the Object class, it is far from complete, but it makes a good example. Just remember when you are using reference counting and you have a child class referencing a perent class and that parent class referencing that same child class, make the child class using a weak reference (just a pointer), that way memory leaks will not occur from circular dependancies.
Code:
//////////////////////////////////////////////////////////////////////////////
// $Revision$
// $Id$
//////////////////////////////////////////////////////////////////////////////
#ifndef _OBJECT_H
#define _OBJECT_H
// Everything here is inline, because it is called alot.
class Object {
public:
//Object(): mpCount(new int(1)) {}
//virtual ~Object() { delete mpCount; }
//virtual void Ref() const { ++*mpCount; }
//virtual void Unref() const { if (--*mpCount == 0) delete this; }
//virtual int refCount() const { return *mpCount; }
Object(): mCount(1) {}
virtual ~Object() {}
virtual void Ref() const { ++mCount; }
virtual void Unref() const { if (--mCount == 0) { delete this; } }
virtual int refCount() const { return mCount; }
private:
//int* mpCount;
mutable int mCount;
};
#endif // _OBJECT_H
//////////////////////////////////////////////////////////////////////////////
// $Log$
//////////////////////////////////////////////////////////////////////////////
// vim:ts=2:sw=2:sts=2:et
class A: virtual public Object {
. . . Some stuff . . .
};
int main()
{
A B;
Ref<A> rA = new A;
Ref<A> rA2 = A;
Ref<A> rA3 = B;
. . . Some more stuff . . .
return 0;
}
There is no need for Unref() or delete in the sample code above, the Ref<T> class template does everything for you through the Object class. Note: B in the above example uses stack space and is not accidently freed, because Ref<T> addeds an extra reference to make sure the reference count does not hit zero.
Last edited by clinux_rulz; 12-17-2005 at 09:33 AM.
Reason: slashes the wrong way in code blocks
In the two examples any of the mPhysicsObjects are referenced to a PhysicsObject, where as each of the PhysicsObject's mpParent(s) are weakly referenced back to the PhysicsSystem it belongs too.
The type PhysicsSystem* is a weak reference, because it is a pointer without any reference counting.
The type Ref<PhysicsObject> is a actual reference, that will do reference counting, and hits zero and deletes itself once nobody is using the PhysicsObject that it references anymore.
Sometimes a system can be too complex to correctly implement with a combination of References and Weak References, in which case Garbarge Collection is a ok idea. Garbages Collection is faster than reference counting, because it does not have to update a counter, and because it does not have to free any memory until any criterion to Collect the Garbage has been meet.
Most the time reference counting should be ok, but do not over use it. Only use it in areas which it is helpful, do not use it for everything. If you have an instance of an object that is only used by one piece of code (like a single class), then do not use reference couning. But if you have an object that a heap of classes may contain, and the order of destruction of the classes is not predetermined or can happen in any order, then do use reference counting.
When using reference counting be carefull to make sure there are no circular dependances, and eleminate any circular dependances with a weak reference. E.g. a doubling linked list with references for the nodes (maybe because the nodes can be spliced together in a specialised list, mimicing a tree), then make the nodes have a Reference to the next node and just a Weak reference to the previous node. Then when you are done unreference the first node and what them all blow up like a chain reaction, until you list is freed.
Unfortunatly if you were implementing a circular list you would have a circular dependance still event with the implementation described in the previos paragraph. And in this case you might now want to use Reference Counting or just simply have a flag at the end of the list where the tail joins to the front so you can double unreference.
If you need a pointer to an object that will automatically free itself, and is only needed by one section or piece of code, then you can use Auto Pointers.
Auto pointer you can just treat as pointers, plus unlike normal pointers you can still easly free there memory in the point of an exception, almost like a stacky dynamic memory type of thing.
One problem is that if you wanted more that the one copy of this object, you would have to make more exact copies instead of using the same one.
AutoPtr<Crap>* pMyCrap = new Crap;
AutoPtr<Crap>* pACopyOfMyCrap = new Crap(*pMyCrap);
So on the down side it uses more memory, but on the up side no memory leaks.
Sometimes this can be just as bad as stack variables, and your just better of using them.
AutoPtr(s) are good when you do not have the information to create the object until a function is called that supplies the information. Sort of like delayed construction. Like a render function for a 3d model might supply the plugin for the video at render time, but not at the loading time of the 3d model, so the loading of the textures can be delayed until the video plugin can allocate a texture from video memory to give to the 3d model to use for rendering, then in the next render the texture is no longer needed to be allocated.
that's a hard topic
i had to read it twice to understand ;-)
but how does garbace collection work?
are AutoPtr the only way in C++?
i mean i understand how php or java garbace collection may work
those languages are interpreted so it's more or less easy
but in C/C++ it seems a challenge to do it correctly
Garbage collection works too, but it is a fair amount of work. It involves creating a seperate thread on low priority to check the memory once in a while, and you also must overload your new, new[], delete, delete[] operators, and your malloc() and free() functions, if you entend to use them as well.
To create the platform independand thread for the garbage collection you can use SDL_Thread from the SDL library.
When memory is allocated, extra space for a void* should be allocated as well, so that all allocated objects can be linked together in a forward singular link list fasion. Also you should store the location of the head and the tail of the list as static void pointers in the source file for garbage collection. When new memory is allocated it must be linked on the tail, and when the garbage is collected all the memory should be freed following from the head node onwards.
Also add a dummy class with a dummy static object in your garbage collection source to make sure the all the garbage is collected, so that the garbage is collected before your application terminates.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.