Memory leak

A

Alan Johnson

John said:
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/using_auto_ptr_effectively.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
 
J

JKop

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
 
J

JKop

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
 
A

Alan Johnson

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
 
J

John

JKop said:
John posted:



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
 
J

John

JKop said:
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
 
J

JKop

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
 
J

JKop

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
 
B

Bill Seurer

JKop said:
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.
 
A

Anil Mamede

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
 
J

JKop

Bill Seurer posted:
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.
 
B

Bill Seurer

JKop said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top