How can I write this same code without the use of dynamic allocation?
Thanx,Code:class AClass {
BClass *ptr;
public:
AClass() : ptr(new BClass (10)) {}
};
John
Printable View
How can I write this same code without the use of dynamic allocation?
Thanx,Code:class AClass {
BClass *ptr;
public:
AClass() : ptr(new BClass (10)) {}
};
John
If there are no circular dependencies you can simply write
Code: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.Quote:
Originally Posted by GNiewerth
You could do the following:
Code:class AClass {
BClass bClass;
public:
AClass() : bClass(10) {}
};
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
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.Quote:
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?
In the original code: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:Code:class AClass
{
BClass *ptr;
public:
AClass() : ptr(new BClass (10)) {}
};
Which avoids code clutter. Initializer list is mandatory for ONLY following cases:Code:AClass()
{
ptr = new BClass (10);
}
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.
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.
Yes, I think the important point is that it is safer not to use new in the initialisation list: GotW #66: Constructor Failures. In particular:Quote:
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:
Quote:
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.
Thanks for the replies.
So basically memory leak should be handled by the destructor, using delete etc. What about repeated deletion?
Thanx,
John
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.Quote:
What about repeated deletion?
repeated delete can be avoided by checking the pointer before attempting to delete it.Quote:
Originally Posted by JohnSmith70
(same as what laserlight said, with example)
i.e.
Code:if(ptr)
{
delete ptr;
ptr = 0;
}
1. Check the pointer - only attempt to delete if !NULL
2. delete pointer
3. set pointer to NULL
Not necessary. Deleting a null pointer is perfectly okay.Quote:
1. Check the pointer - only attempt to delete if !NULL
I did not know that.Quote:
Originally Posted by laserlight
Thanks.
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.
Here's the flavor of double deletion that a beginner is most likely to encounter:
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.Code:class Foo
{
public:
Foo()
{
m_ptr = new int;
}
~Foo()
{
delete m_ptr;
}
private:
int * m_ptr;
};
int main()
{
Foo a;
Foo b(a);
}
EDIT: Lindley beat me to it.
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:
Can we delete ordinary variables as well?Code:AClass *ptr;
...
~AClass() { delete ptr; }
Thank you very muchCode:AClass *ptr;
string name;
int number =10;
...
~AClass() { delete ptr; delete name; delete number;
}
John
Quote:
Originally Posted by JohnSmith70
You only delete what you allocate. (HEAP variables)
The other variables are on the stack and are removed as the fall out of scope.
An example:
At the closing brace, the stack variables are automatically popped from the stack (removed from memory) as they fall out of scope.Code:
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;
}
The memory pointed to by pHeap is only released when you call delete for it.
The compiler itself will not allow to 'delete' non-pointers! ;)Code:AClass *ptr;
string name;
int number =10;
...
~AClass() { delete ptr; delete name; delete number;
}