help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Anyone could help me with this memeory problem...


From: Zhou Lei
Subject: Re: Anyone could help me with this memeory problem...
Date: Thu, 24 Feb 2005 00:33:52 +0000
User-agent: Mozilla Thunderbird 1.0 (X11/20041206)

Paul Pluzhnikov wrote:
Zhou Lei <dark_eaglet@hotmail.com> writes:


Thanks for your reply, and yes it is not a good style without checking
the excptions. In this program, the ntree() will return 0 to the
calling statement if this==0, so "p->lchild=lchild->ntree()" has the
same meaning with "p->lchild=(lchild ? lchild->nree() : 0) that you
wrote.


Calling member function on NULL pointer invokes undefined behavior;
don't do this.


And I am confused why "new" failed to allocate memory on my
machine


It didn't.

just crash and say "segmentation fault").


Your program crashed for a totally different reason.
Here is a clue from Insure++:

[junk.cpp:80] **READ_DANGLING**

    lchild->cleanup();


  Reading from a dangling pointer: this, while accessing field "lchild"

  Pointer : 0x0804fab0
  In block: 0x0804fab0 thru 0x0804fabf (16 bytes)
                  p, allocated at junk.cpp, 46
                    ptree::ntree()  pc: 0x08049b7e  junk.cpp, 46
                    ptree::ntree()  pc: 0x08049bd5  junk.cpp, 47
                    ptree::ptree()  pc: 0x08049772  junk.cpp, 31
                            main()  pc: 0x0804a59d  junk.cpp, 94

stack trace where memory was freed:
                            free()  pc: 0x4004cc79  (interface)
                __builtin_delete()  pc: 0x4021714e
                   ptree::~ptree()  pc: 0x0804b282  junk.cpp, 23
                  ptree::cleanup()  pc: 0x0804a1fe  junk.cpp, 82
                  ptree::cleanup()  pc: 0x0804a16e  junk.cpp, 80
                   ptree::~ptree()  pc: 0x0804b1f3  junk.cpp, 21
                            main()  pc: 0x0804ab01  junk.cpp, 109

  Stack trace where the error occurred:
                  ptree::cleanup()  pc: 0x0804a142  junk.cpp, 80
                   ptree::~ptree()  pc: 0x0804b1f3  junk.cpp, 21
                  ptree::cleanup()  pc: 0x0804a1fe  junk.cpp, 82
                   ptree::~ptree()  pc: 0x0804b1f3  junk.cpp, 21
                            main()  pc: 0x0804ab01  junk.cpp, 109

... more errors follow ...

Another (free) tool that can detect these kinds of problems on
Linux/x86 is Valgrind (I advise you to use it regularly). Its message
is slightly more cryptic, but it is telling you about the exact
same problem:

==2136== Invalid read of size 4
==2136==    at 0x8048915: ptree::cleanup(void) (junk.cpp:80)
==2136==    by 0x8048E03: ptree::~ptree(void) (junk.cpp:21)
==2136==    by 0x8048938: ptree::cleanup(void) (junk.cpp:82)
==2136==    by 0x8048E03: ptree::~ptree(void) (junk.cpp:21)
==2136==    by 0x8048C20: main (junk.cpp:109)
==2136==    by 0x402919CA: __libc_start_main (in /lib/libc-2.1.3.so)
==2136==    Address 0x40F9E26C is 8 bytes inside a block of size 16 free'd
==2136==    at 0x40166C20: __builtin_delete (vg_clientfuncs.c:199)
==2136==    by 0x8048E21: ptree::~ptree(void) (junk.cpp:22)
==2136==    by 0x8048938: ptree::cleanup(void) (junk.cpp:82)
==2136==    by 0x804891D: ptree::cleanup(void) (junk.cpp:80)
==2136==    by 0x8048E03: ptree::~ptree(void) (junk.cpp:21)
==2136==    by 0x8048C20: main (junk.cpp:109)
==2136==    by 0x402919CA: __libc_start_main (in /lib/libc-2.1.3.so)

If you still do not understand what the bug in your program is,
say so and it will be revealed to you.

Cheers,

Thank you for your post! The information you provided is very useful and I found the bugs in my programs:

1. As you mentioned calling member functions on NULL pointer is dangerous: maybe in that function we access the member variables that does NOT exist in fact. So the assignment statement now is changed to "lchild = (lc ? lc->ntree() : 0);" to avoid this happens. 2. When at the end of the scope of an object or we delete the pointer to the object explicitly, delete is invoked and the memory delete always calls the destructor. In my code, the destructor ~ptree() called a recursive function cleanup() which contains delete statement, meaning that the stack frame will be like: ~ptree() => cleanup() => ~ptree(), making the same memory area released TWICE! Now I have changed the code and, it seems works smoothly. The code is attached in the attachment.

Valgrind is really a nice tool helping debugging and I think every newbies should use it to save time. Thank you very much and I understand the problem now. :-)

Cheers,


reply via email to

[Prev in Thread] Current Thread [Next in Thread]