GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 26-Jul-2005, 07:52
karthikeyansen karthikeyansen is offline
Awaiting Email Confirmation
 
Join Date: Mar 2005
Location: INDIA
Posts: 22
karthikeyansen is on a distinguished road

Dynamic memory allocation - Dangling pointers revisited


Could you help me detect the problem. As i suspect there must be a dangling pointer to this code.But it behaves fine.

When it comes to the destructor code also, after delete [] ptr, it is printing the values correctly as it is unexpected and that the heap memory should have been reclaimed.

CPP / C++ / C Code:
#include <iostream.h>
class dynamic
{

  int *ptr;
  
 public:
  dynamic()
  {
      cout<<"\n\nwe r at constructor  "<<this<<"\n\n";
   
  }
   
  int* func1(void);
   
  ~dynamic()
  {
      cout<<"\n\nwe r at destructor"<<this<<endl;
 
 if(ptr)
   {
       cout<<"\n\nattribute deletion\n\n";
       cout<<"The value of ptr[0] before delete ="<<ptr[0]<<"\n\nadress of ptr before delete "<<ptr<<"\n\n";
       delete [] ptr;
       cout<<"The value of ptr[0] after delete ="<<ptr[0]<<"\n\nadress of ptr after delete "<<ptr<<"\n\n";
    }

   }
  };


 int* dynamic::func1()
 {
      cout<<"Inside Func1"<<endl<<endl;
      ptr =new int[2];
      ptr[0] = 23;
      cout<<"The value of ptr[0] ="<<ptr[0]<<"\n\nadress of ptr "<<ptr<<"\n\n";
      return ptr;
  }
  
  
  
  int* func()
  {
       dynamic obj;
       cout<<"\n\nwe r at function\n\n";
       int *fptr=obj.func1(); 
       cout<<"\n\nthe value of Fptr :"<<*fptr<<"\n\n"<<"address "<<fptr<<"\n\n";
      return fptr;
   }
   
   int main()
   {
       //dynamic f1;
       //f1.func1();
       int* mptr=func();
       cout<<"\n\nthe value of Mptr:"<<*mptr<<"\n\nadress of Mptr"<<mptr<<endl;
       cout<<"\n\nwe r at main\n\n";
       return 0;
   } 
    
  #2  
Old 26-Jul-2005, 10:16
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,791
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by karthikeyansen
Could you help me detect the problem. As i suspect there must be a dangling pointer to this code.But it behaves fine.

When it comes to the destructor code also, after delete [] ptr, it is printing the values correctly as it is unexpected and that the heap memory should have been reclaimed.

When you delete (or delete []) something, it tells the system that you aren't going to use that memory any more, so it is returned to the heap. If you decide to use that memory after you have deleted it, that is called "undefined" behavour. That is, the contents of that memory may be the same as before you deleted it or not.

Furthermore, there is no way that the system can go back and change the values of any variables that you have used to point to that memory, so the pointer values still point to the memory that used to be yours, even though it isn't yours anymore. It is the program's responsibility to keep track of its pointers. Many people make a practice always to put in code to set the pointer to NULL after a delete so that inadvertant (buggy) subsequent attempts to dereference that pointer will result in an access violation (segment fault).

Regards,

Dave
  #3  
Old 26-Jul-2005, 12:28
alcedo's Avatar
alcedo alcedo is offline
Member
 
Join Date: Jul 2005
Location: Singapore
Posts: 198
alcedo will become famous soon enough
CPP / C++ / C Code:
public:
  dynamic(): ptr(NULL)
  {
      cout<<"\n\nwe r at constructor  "<<this<<"\n\n";
   
  }

  ~dynamic()
  {
         if(ptr != NULL) delete []ptr;
 
  }

in short, i think thats what dave meant
__________________
People should read the rules and regulation before posting!

The Best is yet to be...
  #4  
Old 26-Jul-2005, 14:03
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,791
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by alcedo
CPP / C++ / C Code:

         if(ptr != NULL) delete []ptr;
 

in short, i think thats what dave meant

In fact, in C++, "delete" doesn't care if the pointer is null or not. The Standard says that if you give "delete" a null pointer it will ignore it, so this test is useless (but it's also harmless).

My point was, and is, that the program must do the right thing: after delete is used on a pointer (that was given memory by "new"), any attempt to dereference the pointer results in undefined behavior.


Regards,

Dave
  #5  
Old 26-Jul-2005, 23:17
karthikeyansen karthikeyansen is offline
Awaiting Email Confirmation
 
Join Date: Mar 2005
Location: INDIA
Posts: 22
karthikeyansen is on a distinguished road
Quote:
Originally Posted by davekw7x
Furthermore, there is no way that the system can go back and change the values of any variables that you have used to point to that memory, so the pointer values still point to the memory that used to be yours, even though it isn't yours anymore.

Thanks for the valuable information and that i got a good picture on dynamic memory deallocation.

My doubt my sound silly or trivial but i would like to know as to what will happen without delete operator and that i am trying to make the pointer to NULL in destructor.

CPP / C++ / C Code:
~dynamic()

  {
         if(ptr != NULL) 
        // delete []ptr;
        ptr = NULL;
  }


I definitely know that this is the invitation for disaster as it will lead to a memory leak. This is what most of the books claim and that they touch upon this topic simply saying it frees the memory allocated by new.
But then what is the internal function of delete operator?

I am having this doubt because even after deleting the ptr, the link to the heap through the pointer (that has been deleted) still exists and not withdrawn.We were still able to access the values and infact even modify values and print the same.Anyway it the responsibility of the Programmer to take care.

Actually my understanding(may be even assumption) on "delete" operator is that it withdraws the link from the heap by making the ptr value NULL immediately after delete. So my expectation was that at the worst case, i was expecting something like dereferencing the ptr would lead to catastrophic results. But this did not happen as i was able to access the values even after deleting the ptr.

Considering all these, what exactly is the function of delete operator?

I would hear for a brief explanation in terms of compiler treating the delete operator.

Thanks and Regards,
Karthikeyan.S
INDIA
  #6  
Old 27-Jul-2005, 01:24
WaltP's Avatar
WaltP WaltP is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Midwest US
Posts: 3,258
WaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to all
new will grab a bag of bytes from the heap and add pointers and such to tell the system 'this memory block is in use elsewhere. Keepa-U hands off!' The memory is not cleared so if you start looking at the bytes immediately after allocation the data will contain whatever was there when some other program had the memory. Similar to renting an apartment that was just vacated by someone who didn't clean it. All the dirt and mess is now yours.

delete simply reverses the allocation. You, as the current occupant simple leaves and a "For Rent" sign is put out so the memory can be allocated to someone else. But since you still have a key (the address/pointer) you can visit and see the stuff you left. But when another process gets allocated that memory, they get to have all your stuff and change the locks.
__________________

Got a cough? Go home tonight and eat a whole box of Ex-Lax. Tomorrow, you'll be afraid to cough.
-- Pearl Williams
  #7  
Old 27-Jul-2005, 08:18
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,791
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by WaltP
new will grab a bag of bytes from the heap and add pointers and such to tell the system 'this memory block is in use elsewhere. Keepa-U hands off!'
...

delete simply reverses the allocation.

Great explanation, Walt.

When I said "this test is useless", I meant that testing for non-NULL before calling delete is useless. I should have made it clear that this is what I meant: You should always call "delete" for every thing you got with "new". You pass the pointer value that "new" gave you. If you happen to pass a NULL-valued pointer, "delete" is required to ignore it. If you pass any other value (other than something that "new" gave you), the behavior is undefined.

Regards,

Dave
  #8  
Old 27-Jul-2005, 13:55
alcedo's Avatar
alcedo alcedo is offline
Member
 
Join Date: Jul 2005
Location: Singapore
Posts: 198
alcedo will become famous soon enough
Hmm, so delete is to actually ignore ? lol dint know that .

Quote:
if you pass any other value (other than something that "new" gave you), the behavior is undefined.

Does this mean that u ask your ptr to pt to something else like halfway thru your program ?

like:
CPP / C++ / C Code:
char* ptr;
char ch1 = 'a';
char ch2 = 'b';
ptr = new char[1];
ptr[0] = &ch1;
ptr[0] = &ch2;    //Points to ch2 nw. Illegal ? 
__________________
People should read the rules and regulation before posting!

The Best is yet to be...
  #9  
Old 27-Jul-2005, 15:55
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,791
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by alcedo
Hmm, so delete is to actually ignore ? lol dint know that .



Does this mean that u ask your ptr to pt to something else like halfway thru your program ?

like:
CPP / C++ / C Code:
char* ptr;
char ch1 = 'a';
char ch2 = 'b';
ptr = new char[1];
ptr[0] = &ch1;
ptr[0] = &ch2;    //Points to ch2 nw. Illegal ? 


Now, when I said the "test is useless" I meant that you don't have to test to see if ptr is NULL before you execute "delete ptr". I didn't mean that you don't have to "delete ptr". Walt explained it very well.

Now as to your example:

ptr is a pointer to char, so ptr[0] is a char --- it is semantically the same as (*ptr). ch1 and ch2 are chars, so &ch1 and &ch2 are pointers to char. Your program tries to set a char equal to a pointer to a char. Not allowed in C++.

Once you are given memory (by using "new") you can put anything you want to into that memory. Once you have released the memory back to the operating system (by using "delete"), you must not access that memory again. (And if you don't release the memory back to the operating system, that is called a "memory leak" --- a Bad Thing.)

In the following example, I have commented out the two illegal statements. If you uncomment them, the behavior is undefined. One compiler might give one result and another compiler might give another. A program compiled by one compiler could give one result now and a different result if the exact same program is executed tomorrow. (That's what "undefined behavior" means.)

CPP / C++ / C Code:
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
  char *ptr;
  ptr = new char[5]; // five chars worth of memory: do anything you want to
  ptr[0] = 'a';
  ptr[1] = 'b';
  ptr[2] = 0;

  cout << "ptr[1] = " << ptr[1] << endl;
  strcpy(ptr, "xyz");
  cout << "ptr[1] = " << ptr[1] << endl;
  delete [] ptr;

//
  //ptr[1] = 'x'; // now this is illegal, since the memory no longer belongs to you
  //cout << ptr[1]; // this is undefined (may print 'x' or 'y',
                    // or may do anything else --- including segfault)
  
  return 0;
}

Here is something else that is illegal; maybe that's what you had in mind:

CPP / C++ / C Code:
//
  char *ptr;
  char mychar[3] = {'a', 'b', 0};

  ptr = new char[3];
  ptr = &mychar[0]; // this isn't illegal as far as c++ goes, but now
                    // we can never free up the memory from the previous "new"
//
// do whatever you want, but you are accessing local memory mychar[]
//
  delete [] ptr;    // this is illegal, since ptr now points to something that we
                    //didn't get from "new"



Regards,

Dave
  #10  
Old 27-Jul-2005, 16:16
WaltP's Avatar
WaltP WaltP is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Midwest US
Posts: 3,258
WaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to all
Quote:
Originally Posted by alcedo
Hmm, so delete is to actually ignore ? lol dint know that .
Not quite. If the pointer is NULL, delete will ignore. If pointer is not NULL, delete will delete the pointer or die trying.


Quote:
Originally Posted by alcedo
Does this mean that u ask your ptr to pt to something else like halfway thru your program ?

like:
CPP / C++ / C Code:
char* ptr;
char ch1 = 'a';
char ch2 = 'b';
ptr = new char[1];
ptr[0] = &ch1;
ptr[0] = &ch2;    //Points to ch2 nw. Illegal ? 
No it's not illegal. It's just really bad!!! But your example is not a problem. What you really meant to ask (I think) is:
CPP / C++ / C Code:
char* ptr;
char ch1 = 'a';
char ch2 = 'b';
ptr = new char[10];  // get a buffer
ptr[0] = ch1;        // put something in the buffer
ptr = new char[10];  // get another buffer
ptr[0] = ch2;        // put something in the buffer
That is bad because you didn't free the first buffer, and you don't know where it is because you reloaded the pointer. You now have an allocated buffer floating out there in limbo that you can't free. This is called a memory leak. Do it enough and all your memory disappears causing major system problems.
__________________

Got a cough? Go home tonight and eat a whole box of Ex-Lax. Tomorrow, you'll be afraid to cough.
-- Pearl Williams
 
 

Recent GIDBlogWriting a book by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
[Tutorial] Pointers in C (Part II) Stack Overflow C Programming Language 0 27-Apr-2005 18:36
[Tutorial] Pointers in C (Part I) Stack Overflow C Programming Language 1 08-Apr-2005 19:35
Dynamic Memory Allocation - Offset Pointers wu_weidong C Programming Language 6 24-Feb-2005 10:48
3D array dynamic memory allocation cjwatchdog C Programming Language 3 20-Feb-2004 16:27

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 05:57.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.