By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,897 Members | 1,955 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,897 IT Pros & Developers. It's quick & easy.

Memory leak

P: n/a
Hi all:

When I run my code, I find that the memory that the code uses keeps
increasing.
I have a PC with 2G RAM running Debian linux. The code consumes 1.5G
memory by the time it finishes execution. But I do not think it needs
so much memory. About 500M memory should be enough. I have following
questions about memory leak.
(1).If in my code I only define constructor for my class, and do not
define destructor, will it cause memory leak?
(2).If in my code I only use "new" to declare new object, and do not
use "delete", will it cause memory leak?

For example, in the following code:

void class1::function1()
{
class2 *r1;
class2 *r2 = new class2;
class2 *rr[20];

......

function2(rr);

......
//r1 and r2 are also used in function1().

}

In the above code, I have two classes and I define constructor for the
two classes and do not define destructor. In function1(), I declare
two pointers of class2 and an array of pointer of class2. The array rr
is used to bring back values from function2(). For r2, I do not use
"delete".
Will r1, r2 and the array rr[] cause memory leak?
The two pointers, r1 and r2, and array rr[] are local variables, when
the code exits function1(), these local variables should be released
automatically.
Am I right?

Thanks a lot.

John
Jul 22 '05 #1
Share this Question
Share on Google+
32 Replies


P: n/a

"John" <jo*********@yahoo.com> wrote in message
news:c3**************************@posting.google.c om...
Hi all:

When I run my code, I find that the memory that the code uses keeps
increasing.
I have a PC with 2G RAM running Debian linux. The code consumes 1.5G
memory by the time it finishes execution. But I do not think it needs
so much memory. About 500M memory should be enough. I have following
questions about memory leak.
(1).If in my code I only define constructor for my class, and do not
define destructor, will it cause memory leak?
Depends on the class.
(2).If in my code I only use "new" to declare new object, and do not
use "delete", will it cause memory leak?
Yes.

Its a very simple rule, nothing to do with constructors or destructors. When
your program runs every new allocates some memory, if you don't do a delete
for the same memory then you have a memory leak.


For example, in the following code:

void class1::function1()
{
class2 *r1;
class2 *r2 = new class2;
class2 *rr[20];

......

function2(rr);

......
//r1 and r2 are also used in function1().

}

In the above code, I have two classes and I define constructor for the
two classes and do not define destructor.
That's irrelevant.
In function1(), I declare
two pointers of class2 and an array of pointer of class2. The array rr
is used to bring back values from function2(). For r2, I do not use
"delete".
Will r1, r2 and the array rr[] cause memory leak?
Where are the deletes? There are no deletes so there are memory leaks all
over the place.
The two pointers, r1 and r2, and array rr[] are local variables, when
the code exits function1(), these local variables should be released
automatically.
Am I right?


Wrong. The variables destructed and the memory they occupy is 'released',
BUT the memory they might be pointing to is not released.

void f()
{
X x;
X* xp = new X();
...
}

When you get to the end of this function, the memory for x and xp are both
released. That has nothing to do with the memory pointed to by xp, which is
a completely different thing. The memory for a pointer and the memory that
it points to are not the same thing.

It's very simple, every new must be matched by a delete.

john
Jul 22 '05 #2

P: n/a

"John" <jo*********@yahoo.com> wrote in message
news:c3**************************@posting.google.c om...
Hi all:

When I run my code, I find that the memory that the code uses keeps
increasing.
I have a PC with 2G RAM running Debian linux. The code consumes 1.5G
memory by the time it finishes execution. But I do not think it needs
so much memory. About 500M memory should be enough. I have following
questions about memory leak.
(1).If in my code I only define constructor for my class, and do not
define destructor, will it cause memory leak?
(2).If in my code I only use "new" to declare new object, and do not
use "delete", will it cause memory leak?

For example, in the following code:

void class1::function1()
{
class2 *r1;
class2 *r2 = new class2;
class2 *rr[20];

......

function2(rr);

......
//r1 and r2 are also used in function1().

}

In the above code, I have two classes and I define constructor for the
two classes and do not define destructor. In function1(), I declare
two pointers of class2 and an array of pointer of class2. The array rr
is used to bring back values from function2(). For r2, I do not use
"delete".
Will r1, r2 and the array rr[] cause memory leak?
The two pointers, r1 and r2, and array rr[] are local variables, when
the code exits function1(), these local variables should be released
automatically.
Am I right?

Thanks a lot.

John

Hi,
check out "auto_ptr" from any standard c++ boooks.

kutty
Jul 22 '05 #3

P: n/a
Ian
John wrote:
Hi all:

When I run my code, I find that the memory that the code uses keeps
increasing.
I have a PC with 2G RAM running Debian linux. The code consumes 1.5G
memory by the time it finishes execution. But I do not think it needs
so much memory. About 500M memory should be enough. I have following
questions about memory leak.
(1).If in my code I only define constructor for my class, and do not
define destructor, will it cause memory leak?
See next answer! (2).If in my code I only use "new" to declare new object, and do not
use "delete", will it cause memory leak?
Yes, without a destructor, how is the memory you allocated in the
destructor freed?

An alternative is to use std::auto_ptr rather than a plain pointer.

As a rule, any class with pointers must have a destructor and copy
constructor (if nothing else, this makes you think about ownership of
the data you reference through a pointer).

Ian
For example, in the following code:

void class1::function1()
{
class2 *r1;
class2 *r2 = new class2;
class2 *rr[20];

......

function2(rr);

......
//r1 and r2 are also used in function1().

}

In the above code, I have two classes and I define constructor for the
two classes and do not define destructor. In function1(), I declare
two pointers of class2 and an array of pointer of class2. The array rr
is used to bring back values from function2(). For r2, I do not use
"delete".
Will r1, r2 and the array rr[] cause memory leak?
The two pointers, r1 and r2, and array rr[] are local variables, when
the code exits function1(), these local variables should be released
automatically.
Am I right?

Thanks a lot.

John

Jul 22 '05 #4

P: n/a

"Ian" <no***@nowhere.com> wrote in message
news:10***************@drone5.qsi.net.nz...
John wrote:
Hi all:

When I run my code, I find that the memory that the code uses keeps
increasing.
I have a PC with 2G RAM running Debian linux. The code consumes 1.5G
memory by the time it finishes execution. But I do not think it needs
so much memory. About 500M memory should be enough. I have following
questions about memory leak.
(1).If in my code I only define constructor for my class, and do not
define destructor, will it cause memory leak?


See next answer!
(2).If in my code I only use "new" to declare new object, and do not
use "delete", will it cause memory leak?

Yes, without a destructor, how is the memory you allocated in the
destructor freed?

An alternative is to use std::auto_ptr rather than a plain pointer.

As a rule, any class with pointers must have a destructor and copy
constructor (if nothing else, this makes you think about ownership of
the data you reference through a pointer).

Ian


I think the OP is not talking about a class with pointers but a pointer to a
class. Certainly that is what his code shows.

In any case the rule is every new must be matched with a delete.
Constructors and destructors are just a useful way of making sure that this
rule is followed.

Since the OP is clearly struggling with pointers I would advise avoid using
new where possible. It's certainly a common newbie trait to use new where it
isn't necessary.

// newbie style coding
void func()
{
X* xp = new X;
x->some_func();
delete x;
}

// simpler, safer and better coding
void func()
{
X x;
x.some_func();
}

There's nothing in the code that John posted that indicated he must use new
at all.

john
Jul 22 '05 #5

P: n/a
John wrote:
Hi all:

When I run my code, I find that the memory that the code uses keeps
increasing.
I have a PC with 2G RAM running Debian linux. The code consumes 1.5G
memory by the time it finishes execution. But I do not think it needs
so much memory. About 500M memory should be enough. I have following
questions about memory leak.
(1).If in my code I only define constructor for my class, and do not
define destructor, will it cause memory leak?
That depends on what the class does. If it allocates any resources, it
should have a destructor that deallocates them.
(2).If in my code I only use "new" to declare new object, and do not
use "delete", will it cause memory leak?
Yes. Everything you got from new should be deleted as soon as you don't
need it anymore.
For example, in the following code:

void class1::function1()
{
class2 *r1;
class2 *r2 = new class2;
class2 *rr[20];

......

function2(rr);

......
//r1 and r2 are also used in function1().

}

In the above code, I have two classes and I define constructor for the
two classes and do not define destructor. In function1(), I declare
two pointers of class2 and an array of pointer of class2. The array rr
is used to bring back values from function2(). For r2, I do not use
"delete".
Will r1, r2 and the array rr[] cause memory leak?
If you don't delete them, yes. However, since the pointers are local
variables within your function and not member variables of your class,
you don't need a destructor for cleaning them up, but rather would
delete them in the function. Do you actually need them to be pointers
anyway? If a direct instance suffices, use it.
The two pointers, r1 and r2, and array rr[] are local variables, when
the code exits function1(), these local variables should be released
automatically.
The local variables are, but not the objects they point to.
Am I right?


What you wrote is right, but I don't think it's what you meant :-)

Jul 22 '05 #6

P: n/a
John wrote:
Hi all:

When I run my code, I find that the memory that the code uses keeps
increasing.
I have a PC with 2G RAM running Debian linux. The code consumes 1.5G
memory by the time it finishes execution. But I do not think it needs
so much memory. About 500M memory should be enough. I have following


Maybe you're creating objects inside a infinit while or for loop.

Anil Mamede

Jul 22 '05 #7

P: n/a

Where you use "new", you must use "delete".

Where you use "new", you must use "delete".

Where you use "new", you must use "delete".
class2* r2 = new class2;

delete r2;

I highly suggest that you keep the asterisk beside THE CLASS NAME rather
than beside the variable name.

Think of "delete" as a function that takes one paramater, a pointer. You
pass it the value of the variable "r2", which is of type "class2*".

delete r2;
---
As for normal run-of-the-mill variables, they come into being at the
beginning of the block of code and are destroyed at the end of the block of
code:
int main(void)
{ //Right here, a comes into being

class2 a;

{ //Right here, b comes into being

class2 b;

} // Right here, b is destroyed.
return 0;

} //Right here, a is destroyed

Jul 22 '05 #8

P: n/a
JKop wrote:
Think of "delete" as a function that takes one paramater, a pointer.
You pass it the value of the variable "r2", which is of type
"class2*".

delete r2;
I'd rather say think of new as a source and delete as a sink. Everything
that came from 'new' has to go to 'delete'.
As for normal run-of-the-mill variables, they come into being at the
beginning of the block
No, they start existing where they are defined.
of code and are destroyed at the end of the
block of code:
int main(void)
{ //Right here, a comes into being
Nope. a doesn't exist yet.
class2 a;
Here, a commes into existance.

{ //Right here, b comes into being
No. Same as a

class2 b;
} // Right here, b is destroyed.
return 0;

} //Right here, a is destroyed


Jul 22 '05 #9

P: n/a
"John Harrison" <jo*************@hotmail.com> wrote in message news:<2g************@uni-berlin.de>...
"Ian" <no***@nowhere.com> wrote in message
news:10***************@drone5.qsi.net.nz...
John wrote:
Hi all:

When I run my code, I find that the memory that the code uses keeps
increasing.
I have a PC with 2G RAM running Debian linux. The code consumes 1.5G
memory by the time it finishes execution. But I do not think it needs
so much memory. About 500M memory should be enough. I have following
questions about memory leak.
(1).If in my code I only define constructor for my class, and do not
define destructor, will it cause memory leak?


See next answer!
(2).If in my code I only use "new" to declare new object, and do not
use "delete", will it cause memory leak?

Yes, without a destructor, how is the memory you allocated in the
destructor freed?

An alternative is to use std::auto_ptr rather than a plain pointer.

As a rule, any class with pointers must have a destructor and copy
constructor (if nothing else, this makes you think about ownership of
the data you reference through a pointer).

Ian


I think the OP is not talking about a class with pointers but a pointer to a
class. Certainly that is what his code shows.

In any case the rule is every new must be matched with a delete.
Constructors and destructors are just a useful way of making sure that this
rule is followed.

Since the OP is clearly struggling with pointers I would advise avoid using
new where possible. It's certainly a common newbie trait to use new where it
isn't necessary.

// newbie style coding
void func()
{
X* xp = new X;
x->some_func();
delete x;
}

// simpler, safer and better coding
void func()
{
X x;
x.some_func();
}

There's nothing in the code that John posted that indicated he must use new
at all.

john


Hi John,

Thanks a lot.
My code is based on an old code. I modify it and add my own functions.
The old code uses linked list of objects everywhere. The linked list
is implemented by using pointer. This is the reason why I must use
pointer to a class.
If I do not use "new", will it cause memory leak?
For example,

void func()
{
int *p = 0; // Initialize p to be 0.
int a = 10;
X *x; //line 1
x->some_func();
p = & a;
}

Will the above code cause memory leak?
When line 1 is executed, the constructor of X will initialize x. By
the end of func(), x is released. Am I right?

Thanks again.

John
Jul 22 '05 #10

P: n/a

"John" <jo*********@yahoo.com> wrote in message
news:c3**************************@posting.google.c om...
"John Harrison" <jo*************@hotmail.com> wrote in message news:<2g************@uni-berlin.de>...
"Ian" <no***@nowhere.com> wrote in message
news:10***************@drone5.qsi.net.nz...
John wrote:
> Hi all:
>
> When I run my code, I find that the memory that the code uses keeps
> increasing.
> I have a PC with 2G RAM running Debian linux. The code consumes 1.5G
> memory by the time it finishes execution. But I do not think it needs > so much memory. About 500M memory should be enough. I have following
> questions about memory leak.
> (1).If in my code I only define constructor for my class, and do not
> define destructor, will it cause memory leak?

See next answer!
> (2).If in my code I only use "new" to declare new object, and do not
> use "delete", will it cause memory leak?
>
Yes, without a destructor, how is the memory you allocated in the
destructor freed?

An alternative is to use std::auto_ptr rather than a plain pointer.

As a rule, any class with pointers must have a destructor and copy
constructor (if nothing else, this makes you think about ownership of
the data you reference through a pointer).

Ian


I think the OP is not talking about a class with pointers but a pointer to a class. Certainly that is what his code shows.

In any case the rule is every new must be matched with a delete.
Constructors and destructors are just a useful way of making sure that this rule is followed.

Since the OP is clearly struggling with pointers I would advise avoid using new where possible. It's certainly a common newbie trait to use new where it isn't necessary.

// newbie style coding
void func()
{
X* xp = new X;
x->some_func();
delete x;
}

// simpler, safer and better coding
void func()
{
X x;
x.some_func();
}

There's nothing in the code that John posted that indicated he must use new at all.

john


Hi John,

Thanks a lot.
My code is based on an old code. I modify it and add my own functions.
The old code uses linked list of objects everywhere. The linked list
is implemented by using pointer. This is the reason why I must use
pointer to a class.
If I do not use "new", will it cause memory leak?
For example,

void func()
{
int *p = 0; // Initialize p to be 0.
int a = 10;
X *x; //line 1
x->some_func();
p = & a;
}

Will the above code cause memory leak?


No, the above code will crash, x is an uninitalised pointer.
When line 1 is executed, the constructor of X will initialize x.
No, pointers do not have constructors, x is a pointer.
By
the end of func(), x is released. Am I right?


You seem hung up on pointers, often you don't have to use them. Here is the
above program rewritten so that it doesn't use a pointer.

void func()
{
int *p = 0; // Initialize p to be 0.
int a = 10;
X x; // not a pointer
x.some_func(); // no need for a pointer
p = & a;
}

Now because x is not a pointer, there are no problems.

Do not use pointers unless you are sure that you really need them. Linked
lists are one example of where you do need to use pointers, but as you are
finding out using pointers is tricky. If you can I would switch to C++'s
built in linked list class. That should cure your memory leak problems.

john
Jul 22 '05 #11

P: n/a
John wrote:
My code is based on an old code. I modify it and add my own functions.
The old code uses linked list of objects everywhere. The linked list
is implemented by using pointer. This is the reason why I must use
pointer to a class.
If I do not use "new", will it cause memory leak?
No.
For example,

void func()
{
int *p = 0; // Initialize p to be 0.
int a = 10;
X *x; //line 1
x->some_func();
p = & a;
}

Will the above code cause memory leak?
You can't call some_func() on x, because it points into the desert. You
must first let x point to an object before you can use it.
When line 1 is executed, the constructor of X will initialize x.
No, it won't. You seem to be very confused about objects vs. pointers,
construction vs. memory allocation and about the lifetime of object
created in several different ways. I suggest getting a good book about
C++ that explains those concepts in depth. You won't do yourself any
favor if you stick to this trial/error method.
By the end of func(), x is released. Am I right?


Again, x is a pointer. The memory that x (i.e. the pointer) uses will be
freed, nothing more.
Further, the lifetime of an object is independant of whether a pointer
points to it or not, so in your above example, the memory that a takes
will be released when the function returns, but that doesn't have
anything to do with the existance of p.

Jul 22 '05 #12

P: n/a


You are right in that any and all constructors are not called yet, but the
actual memory *is* allocated for the variables at the beginning of the code
block... I think.

Jul 22 '05 #13

P: n/a
John wrote:
Hi all:

When I run my code, I find that the memory that the code uses keeps
increasing.
I have a PC with 2G RAM running Debian linux. The code consumes 1.5G
memory by the time it finishes execution. But I do not think it needs
so much memory. About 500M memory should be enough. I have following
questions about memory leak.
(1).If in my code I only define constructor for my class, and do not
define destructor, will it cause memory leak?
(2).If in my code I only use "new" to declare new object, and do not
use "delete", will it cause memory leak?

For example, in the following code:

void class1::function1()
{
class2 *r1;
class2 *r2 = new class2;
class2 *rr[20];

......

function2(rr);

......
//r1 and r2 are also used in function1().

}


As a thumb rule, make sure that the new and delete operators occur
together in a function body. That makes it easy to maintain and spot the
bugs.

That said, where are you free-ing ( deleting ) the memory allocated
for r2 ( of type class2 ). May be, that might be the culprit.

--
Karthik.
Humans please 'removeme_' for my real email.
Jul 22 '05 #14

P: n/a
"John Harrison" <jo*************@hotmail.com> wrote in message news:<2g************@uni-berlin.de>...
"John" <jo*********@yahoo.com> wrote in message
news:c3**************************@posting.google.c om...
Hi all:

When I run my code, I find that the memory that the code uses keeps
increasing.
I have a PC with 2G RAM running Debian linux. The code consumes 1.5G
memory by the time it finishes execution. But I do not think it needs
so much memory. About 500M memory should be enough. I have following
questions about memory leak.
(1).If in my code I only define constructor for my class, and do not
define destructor, will it cause memory leak?
Depends on the class.
(2).If in my code I only use "new" to declare new object, and do not
use "delete", will it cause memory leak?


Yes.

Its a very simple rule, nothing to do with constructors or destructors. When
your program runs every new allocates some memory, if you don't do a delete
for the same memory then you have a memory leak.


For example, in the following code:

void class1::function1()
{
class2 *r1;
class2 *r2 = new class2;
class2 *rr[20];

......

function2(rr);

......
//r1 and r2 are also used in function1().

}

In the above code, I have two classes and I define constructor for the
two classes and do not define destructor.


That's irrelevant.
In function1(), I declare
two pointers of class2 and an array of pointer of class2. The array rr
is used to bring back values from function2(). For r2, I do not use
"delete".
Will r1, r2 and the array rr[] cause memory leak?


Where are the deletes? There are no deletes so there are memory leaks all
over the place.
The two pointers, r1 and r2, and array rr[] are local variables, when
the code exits function1(), these local variables should be released
automatically.
Am I right?


Wrong. The variables destructed and the memory they occupy is 'released',
BUT the memory they might be pointing to is not released.

void f()
{
X x;
X* xp = new X();
...
}

When you get to the end of this function, the memory for x and xp are both
released. That has nothing to do with the memory pointed to by xp, which is
a completely different thing. The memory for a pointer and the memory that
it points to are not the same thing.


It's very simple, every new must be matched by a delete.


Does it mean the number of "new" is equal to the number of "delete" in
a code?
I think there might be exceptions, for example,

void f(X* x0)
{
X* x1 = new X;
X* x2 = new X;
X* x3 = new X;
...
x1 = x0;
x2 = x0;
x3 = x0;
}

main()
{
....
f(x0);
....
f1(x0);

}

In the above code, x0 exists outside f(). If I "delete" anyone of x1,
x2 and x3 before the end of f(), x0 will be released. So f1() will not
run correctly.
So there is less "delete" than "new".
Am I right?

Thanks.

John (new to C++)
Jul 22 '05 #15

P: n/a
John posted:
void f(X* x0)
{
X* x1 = new X;
X* x2 = new X;
X* x3 = new X;
...
x1 = x0;
x2 = x0;
x3 = x0;
}

main()
{
....
f(x0);
....
f1(x0);

}

Oh Dear God No!
First thing, memorize the following:
Where I use "new", I must use "delete".

Where I use "new", I must use "delete".

Where I use "new", I must use "delete".

Where I use "new", I must use "delete".

Where I use "new", I must use "delete".

Where I use "new", I must use "delete".

Where I use "new", I must use "delete".


void f(X* pX0)
{
X* pX1; //I highly suggest that you prefix the letter
X* pX2; // p to the front of the names of pointer
X* pX3; //variables.

//We have just defined 3 variables of type X*
//These 3 variables, although being pointer variables,
//are just like any other variable! They have an
//address in memory and you can store a value in
//them. It just so happens that the value you store
//in them is a memory address!

//As you can see, I haven't initialized them,
//and therefore, they can contain any value!

pX1 = new X; //Here, I have set the value of the
//variable pX1.

//"new" is a sort-of function, what it does is
//allocate memory for an object of size sizeof(X) , and then
//it calls any constructors applicable to X .
//It then returns a value of type X* , having
//allocated the memory. You want to keep note of the
//address of this memory you've allocated, so you can
//actually access it in the future - and what better way
//and place to store it than in a pointer variable!

pX2 = new X;
pX3 = new X;

pX1 = pX0;
pX2 = pX0;
pX3 = pX0;

//You have just set the value of these 3 variables
//to some other value. One result is that now you
//no longer know the address of the memory you
//allocated using "new". Therefore, how the hell
//are you going to free that memory via a call to
//"delete"?, as you must specify the address of the
//previously allocated memory! Doh! And why is this so
//bad? Because the memory NEVER gets freed, even after
//you've exited your program. Then, if you run your
//program again, more memory is "leaked". If you
//continually do this, it *will* add up, especially on
//systems that are seldom turned off, eg. internet web
//servers.
}

main()
{
....
f(&X0); // I assume that you want to pass the address
// of a variable of type X and of name X0
....
f1(&X0);

}

-JKop
Jul 22 '05 #16

P: n/a
> >
It's very simple, every new must be matched by a delete.

Does it mean the number of "new" is equal to the number of "delete" in
a code?


No, I mean that at run time every new must be matched by a delete. Often but
not always that means the news and delete are matched in code, but not
necessarily.
I think there might be exceptions, for example,

void f(X* x0)
{
X* x1 = new X;
X* x2 = new X;
X* x3 = new X;
...
x1 = x0;
x2 = x0;
x3 = x0;
}

main()
{
....
f(x0);
....
f1(x0);

}

In the above code, x0 exists outside f(). If I "delete" anyone of x1,
x2 and x3 before the end of f(), x0 will be released. So f1() will not
run correctly.
So there is less "delete" than "new".
Am I right?


Well I don't think you chosen a good example, because you have three memory
leaks in f.

Here's a simpler example

void delete_me(X* xp)
{
delete xp;
}

int main()
{
X* x1 = new X;
delete_me(x1);
X* x2 = new X;
delete_me(x2);
}

In the code there are two news and one delete. But at run time, new is
called twice and so is delete.

john
Jul 22 '05 #17

P: n/a
John wrote:

Does it mean the number of "new" is equal to the number of "delete" in
a code?
I think there might be exceptions, for example,

void f(X* x0)
{
X* x1 = new X;
X* x2 = new X;
X* x3 = new X;
...
x1 = x0;
x2 = x0;
x3 = x0;
}

main()
{
....
f(x0);
....
f1(x0);

}

In the above code, x0 exists outside f(). If I "delete" anyone of x1,
x2 and x3 before the end of f(), x0 will be released. So f1() will not
run correctly.
So there is less "delete" than "new".
Am I right?


When you run this code, the following is happening:

in main there exists x0

x0
+-----------+
| |
+-----------+

then comes the function call to f.
In f new variables are created and initalized

X* x1 = new X;
X* x2 = new X;
X* x3 = new X;

That means:

x0
+-----------+
| |
+-----------+
f::x1
+-------+ +-------------+
| o------------------------------->| |
+-------+ +-------------+

f::x2
+-------+ +-------------+
| o------------------------------->| |
+-------+ +-------------+

f::x3
+-------+ +-------------+
| o------------------------------->| |
+-------+ +-------------+

And now you do:

x1 = x0; // x0 beeing the address of variable x0 in main
x0
+-----------+
| |<+
+-----------+ |
|
|
f::x1 |
+-------+ | +-------------+
| o---------+ | |
+-------+ +-------------+
You are certainly right, that you must not do a delete on x1, since this
will try to free the memory occupied by variable x0. But look at the
lonely rectangle. There is no pointer pointing to it anymore, which
means you have no way of freeing it again: you created a memory leak.

The sequence:

delete x1;
x1 = x0;

on the other hand will do:

This was the starting situation after the allocations

x0
+-----------+
| |
+-----------+
f::x1
+-------+ +-------------+
| o------------------------------->| |
+-------+ +-------------+

delete x1

x0
+-----------+
| |
+-----------+
f::x1
+-------+
| o------------------------------->
+-------+

x1 = x0;

x0
+-----------+
| |<+
+-----------+ |
|
|
f::x1 |
+-------+ |
| o---------+
+-------+

and as you can see, there is no longer a rectangle sitting
in memory with no pointer to it: no memory leak.

So the correct sequence in your example would be:

void f(X* x0)
{
X* x1 = new X;
X* x2 = new X;
X* x3 = new X;
...
delete x1;
x1 = x0;

delete x2;
x2 = x0;

delete x3;
x3 = x0;
}

And as you can see, at runtime there is exactly one delete
for every new.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #18

P: n/a
JKop wrote:
You are right in that any and all constructors are not called yet, but
the actual memory *is* allocated for the variables at the beginning of
the code block... I think.


That depends entirely on the implementation. A conforming program cannot
find out what the implementation does.

Jul 22 '05 #19

P: n/a
Hi Karl:
Thank you very much. I understand now.
On this discussion list, there are so many warm-hearted experts who
spend their precious time instructing me--a newbie of C++.
I have two questions. Is the following code free of trouble?
void f()
{
X *x0 = new X(10);//create and initialize an object of class X.
X *x1;
x1 = x0;
delete x1; //release the memory that x0 uses.
}

I do not "delete" x0, but "delete" x1 to release the memory. Will it
cause any problem. An old code that I am modifying uses this approach.

Another question is:
What is the differece between the two lines below:
X *xx = new X;//line 1
X *xx1;//line 2
Line 1 declare xx and allocate it memory.
Line 2 declare xx1 and xx1 points to somewhere unknown. Has xx1 been
allocated memory?

Thanks a lot.

John
Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<40***************@gascad.at>...
John wrote:

Does it mean the number of "new" is equal to the number of "delete" in
a code?
I think there might be exceptions, for example,

void f(X* x0)
{
X* x1 = new X;
X* x2 = new X;
X* x3 = new X;
...
x1 = x0;
x2 = x0;
x3 = x0;
}

main()
{
....
f(x0);
....
f1(x0);

}

In the above code, x0 exists outside f(). If I "delete" anyone of x1,
x2 and x3 before the end of f(), x0 will be released. So f1() will not
run correctly.
So there is less "delete" than "new".
Am I right?


When you run this code, the following is happening:

in main there exists x0

x0
+-----------+
| |
+-----------+

then comes the function call to f.
In f new variables are created and initalized

X* x1 = new X;
X* x2 = new X;
X* x3 = new X;

That means:

x0
+-----------+
| |
+-----------+
f::x1
+-------+ +-------------+
| o------------------------------->| |
+-------+ +-------------+

f::x2
+-------+ +-------------+
| o------------------------------->| |
+-------+ +-------------+

f::x3
+-------+ +-------------+
| o------------------------------->| |
+-------+ +-------------+

And now you do:

x1 = x0; // x0 beeing the address of variable x0 in main
x0
+-----------+
| |<+
+-----------+ |
|
|
f::x1 |
+-------+ | +-------------+
| o---------+ | |
+-------+ +-------------+
You are certainly right, that you must not do a delete on x1, since this
will try to free the memory occupied by variable x0. But look at the
lonely rectangle. There is no pointer pointing to it anymore, which
means you have no way of freeing it again: you created a memory leak.

The sequence:

delete x1;
x1 = x0;

on the other hand will do:

This was the starting situation after the allocations

x0
+-----------+
| |
+-----------+
f::x1
+-------+ +-------------+
| o------------------------------->| |
+-------+ +-------------+

delete x1

x0
+-----------+
| |
+-----------+
f::x1
+-------+
| o------------------------------->
+-------+

x1 = x0;

x0
+-----------+
| |<+
+-----------+ |
|
|
f::x1 |
+-------+ |
| o---------+
+-------+

and as you can see, there is no longer a rectangle sitting
in memory with no pointer to it: no memory leak.

So the correct sequence in your example would be:

void f(X* x0)
{
X* x1 = new X;
X* x2 = new X;
X* x3 = new X;
...
delete x1;
x1 = x0;

delete x2;
x2 = x0;

delete x3;
x3 = x0;
}

And as you can see, at runtime there is exactly one delete
for every new.

Jul 22 '05 #20

P: n/a
John wrote:
Hi Karl:
Thank you very much. I understand now.
On this discussion list, there are so many warm-hearted experts who
spend their precious time instructing me--a newbie of C++.
I have two questions. Is the following code free of trouble?
void f()
{
X *x0 = new X(10);//create and initialize an object of class X.
X *x1;
x1 = x0;
delete x1; //release the memory that x0 uses.
}

I do not "delete" x0, but "delete" x1 to release the memory. Will it
cause any problem. An old code that I am modifying uses this approach.
No problems there. Although it isn't a particularly "safe" way to do
things, because code that is using x0 doesn't necessarily know that the
memory to which it points has been deleted.

If you need to use multiple pointers to point to the same dynamic
memory, try to come up with some scheme that let's you know which
pointer "owns" (i.e., is responsible for deleting) the memory. One
possible approach is as follows:

---
X *x0 = new X(10); // Allocate some memory. This memory is owned by x0.
X *x1 = NULL; // This pointer doesn't own anything, so it is NULL.

f(x0); // Do something with x0.

x1 = x0; // Transfer ownership of memory
x0 = NULL; // to x1.

f(x1); // Do something with x1.

if (x1) delete x1; // Delete the memory, but if and only if x1 owns it.
---
I'd mostly try to just avoid passing ownership of allocated memory
blocks around in the first place, though. Also, depending on what you
are doing, you may try using an auto_ptr to "own" your allocated memory,
so that you don't need to worry about whether or not it gets
deallocated. For example:

void f()
{
auto_ptr<X> x0 = new X(10);
auto_ptr<X> x1;

// Do something with x0.

x1 = x0 ;

// Do something with x1.

} // Ignore the memory, it will get deleted on its own.
A nice auto_ptr tutorial is available here:
http://www.gotw.ca/publications/usin...ffectively.htm

Another question is:
What is the differece between the two lines below:
X *xx = new X;//line 1
X *xx1;//line 2
Line 1 declare xx and allocate it memory.
Line 2 declare xx1 and xx1 points to somewhere unknown. Has xx1 been
allocated memory?
This would all depend on the platform and/or implementation, but for the
sake of discussion, let's say that pointers, on your system, require 4
bytes, and the object you are calling X requires 32 bytes.

Let's look at line 2 first. This allocates 4 bytes of "automatic"
memory. By automatic, we mean that the any allocation and deallocation
of the memory is handled for us by the compiler. This is no different
from declaring an int, double, char, etc. The standard doesn't specify
how this must be implemented, but typically this occurs on what is
referred to as "the stack". What is the value contained in those 4
bytes? We can't really say, because it wasn't initialized.

Now, line 1. Obviously this line must do at least as much as line 2. It
allocates 4 bytes (which happen to have the name xx) of automatic
memory. It also allocates 32 bytes (at least) of dynamic memory.
Dynamic memory means that the programmer is responsible for allocating
and deallocating it, instead of the compiler. In most implementations,
this memory comes from a place called "the heap" or "the free store"
(refer to other posts in this newsgroup for arguments about what to call
this). What is in the 4 bytes called xx? If we look, we should find
that the value there is the memory address at which our 32 byte block
got allocated, which is, of course, why we call it a pointer.
Thanks a lot.

John


Alan
Jul 22 '05 #21

P: n/a
John posted:
void f()
{
X *x0 = new X(10);//create and initialize an object of class X.
X *x1;
x1 = x0;
delete x1; //release the memory that x0 uses.
}

I do not "delete" x0, but "delete" x1 to release the memory. Will it
cause any problem. An old code that I am modifying uses this approach.

Another question is:
What is the differece between the two lines below:
X *xx = new X;//line 1
X *xx1;//line 2
Line 1 declare xx and allocate it memory.
Line 2 declare xx1 and xx1 points to somewhere unknown. Has xx1 been
allocated memory?

The very reason that you ask this question shows that you don't understand
pointer variables. I'll try enlighten you:

int DogAge;
DogAge = 4;

I have declared a variable DogAge . To declare a variable, you need
specify two and only two pieces of information: 1) The type, 2) The token-
name.
In the preceeding example, the type is int and the token-name is DogAge .
Essentially what you're doing when declaring a variable is just allocating a
piece of memory. How much memory is allocated for each variable? This is
determined from the type you specify. For example, for int , it might be
16 Bits. And there you have it: When you write

int DogAge;

you are allocating 16 Bits of memory. The type of the variable also tells
something else, it determines how the variable is *treated*, ie. in what way
is a value represented in those 16 Bits. Here's a few declarations, with a
type and a token-name:

int k;
char t;
double r;
int* s;
char* q;
Here's the part that you don't understand yet:

int* s;

Here, the type is int* and the token-name is s . I am allocating a piece
of memory, the size of which is determined by the type. Let's say that the
size of an int* is 32 Bits. So now, I have allocated 32 Bits of memory,
plain and simple. As I've said, the type name also specifies in what way a
variable is treated and hence what way a value is represented in memory
using those bits. Take the following:

int* s;

s = 4567;
Do you see what I'm getting at? A pointer variable is just like any other
variable. You store a value in it. It just so happens that the value you
store in a pointer variable is a memory address. If you understand this,
then you'll understand that all pointer variables allocate the *same* amount
of memory:

char* k;
double* p;
int* t;

----

Hoping that that has helped, let's look at your code:
void f()
{
X *x0 = new X(10); //I'm going to split this line
//into 2 lines for clarity

X* x0; //Here you have declared a varible

x0 = new X(10); //Here you have copied a value into the
//variable. The value is the memory address
//of the memory allocated by "new"

//"new" is like a function that returns
//the address of the memory allocated
X *x1; //Here you have declared a variable

x1 = x0; //You have copied the value stored in the variable
// x0 into the variable x1

//At this point, x0 and x1 contain the same value
// delete is like a function that takes a memory address
//as a paramter. It wants the memory address of memory
//previously allocated using "new".
//I have a question for you here now. A little test. Would
//there be a difference at this point in writing

delete x1;

//as opposed to writing

delete x0;

//?
}
Hope that helps
-JKop
Jul 22 '05 #22

P: n/a

I anticipate that you may wonder about the difference, if any, between:
int* pNumber;

int *pNumber;
Look at the following:

GetSquareRoot(56);

can be written as
GetSquareRoot(50 + 6);

GetSquareRoot(50 +6);

GetSquareRoot(50+ 6);

GetSquareRoot(50+6);
You can stick in spaces anywhere you want with C++. You can even write a
program all on one line:
int main(void) { int j; j = 4; GetSquareRoot(j); return 0; }

int main(void){intj;j=4;GetSquareRoot(j);return0;}
So, in summation:
int* s;
int *s;
will compile exactly the same. But...
int *s is extremely stupid. This implies that the type of the variable is
int . It's not. The type of the variable is int* , and the name of the
variable is simply s . So always keep the asterisk beside the TYPE!!!
-JKop

Jul 22 '05 #23

P: n/a
JKop wrote:

int *s is extremely stupid. This implies that the type of the variable is
int . It's not. The type of the variable is int* , and the name of the
variable is simply s . So always keep the asterisk beside the TYPE!!!
-JKop


int* s isn't so great either. Consider:

int* s, t, u, v;
What did I just create? It wasn't four variable of type (int*). I
created s of type (int*), and t, u, and v of type (int).

The proper way to do this is (ignoring whitespace styles):

int *s, *t, *u, *v;

Or, you might argue that it would be more proper to use:

int* s;
int* t;
int* u;
int* v;

Really, I prefer not to take sides on the debate, and just say, whatever
you do, do it consistently!

Alan
Jul 22 '05 #24

P: n/a
JKop <NU**@NULL.NULL> wrote in message news:<r5******************@news.indigo.ie>...
John posted:
void f()
{
X *x0 = new X(10);//create and initialize an object of class X.
X *x1;
x1 = x0;
delete x1; //release the memory that x0 uses.
}

I do not "delete" x0, but "delete" x1 to release the memory. Will it
cause any problem. An old code that I am modifying uses this approach.

Another question is:
What is the differece between the two lines below:
X *xx = new X;//line 1
X *xx1;//line 2
Line 1 declare xx and allocate it memory.
Line 2 declare xx1 and xx1 points to somewhere unknown. Has xx1 been
allocated memory?

The very reason that you ask this question shows that you don't understand
pointer variables. I'll try enlighten you:

int DogAge;
DogAge = 4;

I have declared a variable DogAge . To declare a variable, you need
specify two and only two pieces of information: 1) The type, 2) The token-
name.
In the preceeding example, the type is int and the token-name is DogAge .
Essentially what you're doing when declaring a variable is just allocating a
piece of memory. How much memory is allocated for each variable? This is
determined from the type you specify. For example, for int , it might be
16 Bits. And there you have it: When you write

int DogAge;

you are allocating 16 Bits of memory. The type of the variable also tells
something else, it determines how the variable is *treated*, ie. in what way
is a value represented in those 16 Bits. Here's a few declarations, with a
type and a token-name:

int k;
char t;
double r;
int* s;
char* q;
Here's the part that you don't understand yet:

int* s;

Here, the type is int* and the token-name is s . I am allocating a piece
of memory, the size of which is determined by the type. Let's say that the
size of an int* is 32 Bits. So now, I have allocated 32 Bits of memory,
plain and simple. As I've said, the type name also specifies in what way a
variable is treated and hence what way a value is represented in memory
using those bits. Take the following:

int* s;

s = 4567;
Do you see what I'm getting at? A pointer variable is just like any other
variable. You store a value in it. It just so happens that the value you
store in a pointer variable is a memory address. If you understand this,
then you'll understand that all pointer variables allocate the *same* amount
of memory:

char* k;
double* p;
int* t;

----

Hoping that that has helped, let's look at your code:
void f()
{
X *x0 = new X(10); //I'm going to split this line
//into 2 lines for clarity

X* x0; //Here you have declared a varible

x0 = new X(10); //Here you have copied a value into the
//variable. The value is the memory address
//of the memory allocated by "new"

//"new" is like a function that returns
//the address of the memory allocated
X *x1; //Here you have declared a variable

x1 = x0; //You have copied the value stored in the variable
// x0 into the variable x1

//At this point, x0 and x1 contain the same value
// delete is like a function that takes a memory address
//as a paramter. It wants the memory address of memory
//previously allocated using "new".
//I have a question for you here now. A little test. Would
//there be a difference at this point in writing

delete x1;

//as opposed to writing

delete x0;

//?
}


Thanks a lot!
Now I take the test.-:)
Both "delete x1" and "delete x0" release the same memory. But "delete
x1" causes "dangling problem" to x0; "delete x0" causes "dangling
problem" to x1.
Am I right?
By the way, what is the difference between "int* s" and "int *s". My
text book uses "int *s".

Thanks again.

John
Jul 22 '05 #25

P: n/a
JKop <NU**@NULL.NULL> wrote in message news:<tc******************@news.indigo.ie>...
I anticipate that you may wonder about the difference, if any, between:
int* pNumber;

int *pNumber;


Exactly! I post a follow-up to your last post asking this question. I
am clear now. Thanks.

John
Jul 22 '05 #26

P: n/a
Hi Alan:

Thank you very much for the instruction!

John

Alan Johnson <al****@mailandnews.com> wrote in message news:<40********@news.ua.edu>...
John wrote:
Hi Karl:
Thank you very much. I understand now.
On this discussion list, there are so many warm-hearted experts who
spend their precious time instructing me--a newbie of C++.
I have two questions. Is the following code free of trouble?
void f()
{
X *x0 = new X(10);//create and initialize an object of class X.
X *x1;
x1 = x0;
delete x1; //release the memory that x0 uses.
}

I do not "delete" x0, but "delete" x1 to release the memory. Will it
cause any problem. An old code that I am modifying uses this approach.


No problems there. Although it isn't a particularly "safe" way to do
things, because code that is using x0 doesn't necessarily know that the
memory to which it points has been deleted.

If you need to use multiple pointers to point to the same dynamic
memory, try to come up with some scheme that let's you know which
pointer "owns" (i.e., is responsible for deleting) the memory. One
possible approach is as follows:

---
X *x0 = new X(10); // Allocate some memory. This memory is owned by x0.
X *x1 = NULL; // This pointer doesn't own anything, so it is NULL.

f(x0); // Do something with x0.

x1 = x0; // Transfer ownership of memory
x0 = NULL; // to x1.

f(x1); // Do something with x1.

if (x1) delete x1; // Delete the memory, but if and only if x1 owns it.
---
I'd mostly try to just avoid passing ownership of allocated memory
blocks around in the first place, though. Also, depending on what you
are doing, you may try using an auto_ptr to "own" your allocated memory,
so that you don't need to worry about whether or not it gets
deallocated. For example:

void f()
{
auto_ptr<X> x0 = new X(10);
auto_ptr<X> x1;

// Do something with x0.

x1 = x0 ;

// Do something with x1.

} // Ignore the memory, it will get deleted on its own.
A nice auto_ptr tutorial is available here:
http://www.gotw.ca/publications/usin...ffectively.htm

Another question is:
What is the differece between the two lines below:
X *xx = new X;//line 1
X *xx1;//line 2
Line 1 declare xx and allocate it memory.
Line 2 declare xx1 and xx1 points to somewhere unknown. Has xx1 been
allocated memory?


This would all depend on the platform and/or implementation, but for the
sake of discussion, let's say that pointers, on your system, require 4
bytes, and the object you are calling X requires 32 bytes.

Let's look at line 2 first. This allocates 4 bytes of "automatic"
memory. By automatic, we mean that the any allocation and deallocation
of the memory is handled for us by the compiler. This is no different
from declaring an int, double, char, etc. The standard doesn't specify
how this must be implemented, but typically this occurs on what is
referred to as "the stack". What is the value contained in those 4
bytes? We can't really say, because it wasn't initialized.

Now, line 1. Obviously this line must do at least as much as line 2. It
allocates 4 bytes (which happen to have the name xx) of automatic
memory. It also allocates 32 bytes (at least) of dynamic memory.
Dynamic memory means that the programmer is responsible for allocating
and deallocating it, instead of the compiler. In most implementations,
this memory comes from a place called "the heap" or "the free store"
(refer to other posts in this newsgroup for arguments about what to call
this). What is in the 4 bytes called xx? If we look, we should find
that the value there is the memory address at which our 32 byte block
got allocated, which is, of course, why we call it a pointer.
Thanks a lot.

John


Alan

Jul 22 '05 #27

P: n/a
John posted:
Both "delete x1" and "delete x0" release the same memory. But "delete
x1" causes "dangling problem" to x0; "delete x0" causes "dangling
problem" to x1.

It's my opinion that people in the know-how about programming tend to
undermine the intelligence, ingenuity, and creativity of the human mind.
Let's say for example we *do* call:
delete x1;
And as you've said, we have a "dangling problem". I myself am an intelligent
person, I know what's going on in my code, and thus, nothing less than a
brain hemerage would make me fiddle with the memory again after I've freed
it. You'll see that some people may do the following:

delete x1;

x0 = 0;
I myself find this degrading. I'm not sufficently stupid to go messing with
x0 afterwards.

In summation:

I don't recognize or acknowledge "a dangling pointer" as a problem. That's
just my opinion on the subject.
-JKop

Jul 22 '05 #28

P: n/a
Alan Johnson posted:

int* s isn't so great either. Consider:

int* s, t, u, v;
What did I just create? It wasn't four variable of type (int*). I
created s of type (int*), and t, u, and v of type (int).
When I was first enlightened long ago that this statement declares s as
type int* and t u v as type int , I was disgusted. Not much point
talking about it though, that's just how it is. C++ is due for an overhall!


The proper way to do this is (ignoring whitespace styles):

int *s, *t, *u, *v;
The only reason I don't like this is that it suggests:

Type = int
Token-name = *s

Or, you might argue that it would be more proper to use:

int* s;
int* t;
int* u;
int* v;
....it's too beautiful

Really, I prefer not to take sides on the debate, and just say,
whatever
you do, do it consistently!


Although it *would* be more fun to hold a gun to everyone's head and tell
them to do the following:

int* s;
int* t;
int* u;
int* v;
-JKop
Jul 22 '05 #29

P: n/a
> Thanks a lot!
Now I take the test.-:)
Both "delete x1" and "delete x0" release the same memory. But "delete
x1" causes "dangling problem" to x0; "delete x0" causes "dangling
problem" to x1.
Am I right?
By the way, what is the difference between "int* s" and "int *s". My
text book uses "int *s".

Thanks again.

John


It's the same thing. I prefer int* s;

Anil Mamede
Jul 22 '05 #30

P: n/a
JKop wrote:
I don't recognize or acknowledge "a dangling pointer" as a problem. That's
just my opinion on the subject.


That just shows you are not very experienced with real, large projects.
Dangling pointers are a potential HUGE problem in real code. The
example given is so trivial it can be ignored.
Jul 22 '05 #31

P: n/a
Bill Seurer posted:
JKop wrote:
I don't recognize or acknowledge "a dangling pointer" as a problem.
That's just my opinion on the subject.


That just shows you are not very experienced with real, large projects.
Dangling pointers are a potential HUGE problem in real code. The
example given is so trivial it can be ignored.

You're right that I'm not very experienced with real, large projects.

I'm assuming that you are, so I'll take your word for it. But right now, it
seems to me that I'd be more likely to hit the accelerator instead of the
brake than, via a pointer, access memory which *I myself* have previously
deallocated!
Maybe if I ever *do* become a big-time programmer, I may see your point of
view.
Jul 22 '05 #32

P: n/a
JKop wrote:
I'm assuming that you are, so I'll take your word for it. But right now, it
seems to me that I'd be more likely to hit the accelerator instead of the
brake than, via a pointer, access memory which *I myself* have previously
deallocated!


When you work on something that scores if not hundreds of other
programmers are also working on you have to be extremely careful about
memory management.

You allocate some memory and pass it via a pointer off to some code that
you didn't write and don't know the internals of. Later you want to
deallocate that memory. Is it safe to do so? Are you CERTAIN that no
one else has kept a copy of that pointer somewhere along the way?

If stuff like this isn't agreed to up front you will run into dangling
pointer problems (among many other problems) sooner rather than later.
Jul 22 '05 #33

This discussion thread is closed

Replies have been disabled for this discussion.