Click to See Complete Forum and Search --> : Avoiding Dynamic Allocation
JohnSmith70
May 26th, 2008, 09:09 AM
How can I write this same code without the use of dynamic allocation?
class AClass {
BClass *ptr;
public:
AClass() : ptr(new BClass (10)) {}
};
Thanx,
John
GNiewerth
May 26th, 2008, 09:26 AM
If there are no circular dependencies you can simply write
class AClass
{
BClass BC[10];
};
PredicateNormative
May 26th, 2008, 10:32 AM
If there are no circular dependencies you can simply write
class AClass
{
BClass BC[10];
};
I think you've misread the OP's post, since 10 is the value to initialise the BClass with, not that 10 of them are needed.
You could do the following:
class AClass {
BClass bClass;
public:
AClass() : bClass(10) {}
};
JohnSmith70
May 26th, 2008, 11:14 AM
Thanks for the response.
I know that code written this way is prone to memory leak. How can I remove memory leaks from my programs and also avoid repeated deletion?
Thanx,
John
laserlight
May 26th, 2008, 11:21 AM
I know that code written this way is prone to memory leak. How can I remove memory leaks from my programs and also avoid repeated deletion?
If you took the suggestion to store an object instead of a pointer as the member then you do not have to worry about a memory leak.
Ajay Vijay
May 26th, 2008, 11:30 AM
In the original code:
class AClass
{
BClass *ptr;
public:
AClass() : ptr(new BClass (10)) {}
};If there is requirement that you must have pointer to a class-type, you need not to initialize in initializer's list (like above). You can safely do:
AClass()
{
ptr = new BClass (10);
}Which avoids code clutter. Initializer list is mandatory for ONLY following cases:
1. Base class is having non-default constructor.
2. You class is having data member of class-type, which does not have default constructor.
3. For const-data members (basic or class type)
4. For refernce type (X &) - not pointer types.
Lindley
May 26th, 2008, 11:40 AM
Initializer lists should be preferred for most things. However, I'll agree that it's probably a good idea to keep new's out of them.
To avoid a memory leak if you *do* use new in a constructor, use delete in the corresponding destructor.
laserlight
May 26th, 2008, 11:50 AM
If there is requirement that you must have pointer to a class-type, you need not to initialize in initializer's list (like above). You can safely do:
Yes, I think the important point is that it is safer not to use new in the initialisation list: GotW #66: Constructor Failures (http://www.gotw.ca/gotw/066.htm). In particular:
Moral #3: Always perform unmanaged resource acquisition in the constructor body, never in initializer lists. In other words, either use "resource acquisition is initialization" (thereby avoiding unmanaged resources entirely) or else perform the resource acquisition in the constructor body.
Moral #4: Always clean up unmanaged resource acquisition in local try-block handlers within the constructor or destructor body, never in constructor or destructor function-try-block handlers.
JohnSmith70
May 26th, 2008, 02:16 PM
Thanks for the replies.
So basically memory leak should be handled by the destructor, using delete etc. What about repeated deletion?
Thanx,
John
laserlight
May 26th, 2008, 02:26 PM
What about repeated deletion?
Set pointers to NULL after using delete on them (unless the pointer goes out of scope immediately after that). Of course, this will not help if you use delete on another pointer to the same object.
kenrus
May 26th, 2008, 02:45 PM
Thanks for the replies.
So basically memory leak should be handled by the destructor, using delete etc. What about repeated deletion?
Thanx,
John
repeated delete can be avoided by checking the pointer before attempting to delete it.
(same as what laserlight said, with example)
i.e.
if(ptr)
{
delete ptr;
ptr = 0;
}
1. Check the pointer - only attempt to delete if !NULL
2. delete pointer
3. set pointer to NULL
laserlight
May 26th, 2008, 02:48 PM
1. Check the pointer - only attempt to delete if !NULL
Not necessary. Deleting a null pointer is perfectly okay.
kenrus
May 26th, 2008, 02:57 PM
Not necessary. Deleting a null pointer is perfectly okay.
I did not know that.
Thanks.
Lindley
May 26th, 2008, 02:59 PM
More importantly in this case, you'll have to define the operator= and copy constructor in such a way that no two objects of a class share the same pointer. Typically this means allocate a new dynamic object in both cases; and in the case of operator=, also first delete the existing object (if any).
If your operator= and copy constructor are properly defined, then it will be impossible for a destructor call to result in multiple deletion because there will be only one object holding each dynamically allocated memory block.
Hermit
May 26th, 2008, 03:00 PM
Here's the flavor of double deletion that a beginner is most likely to encounter:
class Foo
{
public:
Foo()
{
m_ptr = new int;
}
~Foo()
{
delete m_ptr;
}
private:
int * m_ptr;
};
int main()
{
Foo a;
Foo b(a);
}
Since no copy constructor is provided, both a and b will point to the same memory, and both will try to delete that memory when they fall out of scope. This problem is avoided by writing a proper copy constructor and assignment operator.
EDIT: Lindley beat me to it.
JohnSmith70
May 26th, 2008, 06:49 PM
Thanks to all of your replies, that really helpful.
About the destructors, this may be a silly question. In the destructor can we use "delete" on any variables or do they have to be pointers? Because I've mostly seen code like:
AClass *ptr;
...
~AClass() { delete ptr; }
Can we delete ordinary variables as well?
AClass *ptr;
string name;
int number =10;
...
~AClass() { delete ptr; delete name; delete number;
}
Thank you very much
John
kenrus
May 26th, 2008, 07:01 PM
Thanks to all of your replies, that really helpful.
About the destructors, this may be a silly question. In the destructor can we use "delete" on any variables or do they have to be pointers? Because I've mostly seen code like:
AClass *ptr;
...
~AClass() { delete ptr; }
Can we delete ordinary variables as well?
AClass *ptr;
string name;
int number =10;
...
~AClass() { delete ptr; delete name; delete number;
}
Thank you very much
John
You only delete what you allocate. (HEAP variables)
The other variables are on the stack and are removed as the fall out of scope.
kenrus
May 26th, 2008, 07:09 PM
An example:
int main(int argc, char** argv)
{
//The following are pushed onto the stack as
//they come in to scope (automatically)
int mynum = 0; //Stack
char myarray[128] = {0}; //Stack
char* pHeap = 0; //Stack
//The following is put into heap memory as it is requested
pHeap = new char[256];
//delete / release memory
delete[] pHeap;
}
At the closing brace, the stack variables are automatically popped from the stack (removed from memory) as they fall out of scope.
The memory pointed to by pHeap is only released when you call delete for it.
Ajay Vijay
May 26th, 2008, 10:27 PM
AClass *ptr;
string name;
int number =10;
...
~AClass() { delete ptr; delete name; delete number;
}The compiler itself will not allow to 'delete' non-pointers! ;)
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.