Funny issue with deleting an external C++ object.

6 messages Options
Embed this post
Permalink
Phil Malin-3

Funny issue with deleting an external C++ object.

Reply Threaded More More options
Print post
Permalink
Hi all.

I've got a weird problem that I'm hoping someone's seen before and has
some helpful suggestions.

I'm writing a program which links to a C++ library (FLTK).  The problem
has to do with the destruction of referenced C++ objects - basically I
get a 'Received signal 11' error (segmentation violation) when it tries
to delete the C++ object (I've traced it to the actual delete call).  I
have no problem with creating the C++ object and accessing methods on
it, only when it comes to deleting it.  I wondered if it had to do with
me casting the void* to the appropriate type but since accessing other
methods work and they do the same thing re casting, I can't see how this
is the problem (given my basic knowledge of C++).

Has anyone else encountered this before?  I also wondered if maybe the
Eiffel-generated C code was doing something funny to the object but
after a cursory glance it doesn't seem to be doing anything odd.

I've built this on FreeBSD using gcc 4.2.1 and SmartEiffel 2.3 (I
haven't tried the latest build yet but that was my next avenue).  I'm
also not using any optimisations when compiling the C.

Thanks in advance for any help.

Phil.

Daniel F Moisset-3

Re: Funny issue with deleting an external C++ object.

Reply Threaded More More options
Print post
Permalink
On Wed, Feb 4, 2009 at 10:03 PM, Phil Malin <[hidden email]> wrote:

> Hi all.
>
> I've got a weird problem that I'm hoping someone's seen before and has some
> helpful suggestions.
>
> I'm writing a program which links to a C++ library (FLTK).  The problem has
> to do with the destruction of referenced C++ objects - basically I get a
> 'Received signal 11' error (segmentation violation) when it tries to delete
> the C++ object (I've traced it to the actual delete call).  I have no
> problem with creating the C++ object and accessing methods on it, only when
> it comes to deleting it.  I wondered if it had to do with me casting the
> void* to the appropriate type but since accessing other methods work and
> they do the same thing re casting, I can't see how this is the problem
> (given my basic knowledge of C++).

Things that I think may be related:
 are you using "delete" instead of "delete[]" ?
 have you got any other memory usage problems? compiling with -g and
using tools like valgrind or gdb may help.

Errors on delete/free() are common when the heap got corrupted. The
corruption may have happened a long time before the free() call, and
in a completely unrelated piece of code. If you can get the program to
run under valgrind or some memory debugger, it usually helps a lot.

Regards,
    D.
Julien Blanc-2

Re: Funny issue with deleting an external C++ object.

Reply Threaded More More options
Print post
Permalink
>
> On Wed, Feb 4, 2009 at 10:03 PM, Phil Malin <[hidden email]> wrote:
>> Hi all.
>>
>> I've got a weird problem that I'm hoping someone's seen before and has some
>> helpful suggestions.
>>
>> I'm writing a program which links to a C++ library (FLTK).  The problem has
>> to do with the destruction of referenced C++ objects - basically I get a
>> 'Received signal 11' error (segmentation violation) when it tries to delete
>> the C++ object (I've traced it to the actual delete call).  I have no
>> problem with creating the C++ object and accessing methods on it, only when
>> it comes to deleting it.  I wondered if it had to do with me casting the
>> void* to the appropriate type but since accessing other methods work and
>> they do the same thing re casting, I can't see how this is the problem
>> (given my basic knowledge of C++).

If you cast your pointer to/from void*, you should always make sure you do the
same casts, in reverse order. This is a common mistake, and it especially
doesn't work when dealing with multiple inheritance. (ie, even if B inherits
from A, dont do the following : (A*)((void*)(new B())).

Also, make sure you don't delete it twice.

Deleting void* is undefined behaviour.

Deleting anything that has not been created by new is undefined behaviour.

> Things that I think may be related:
>  are you using "delete" instead of "delete[]" ?

new -> delete
new[] -> delete[]

>  have you got any other memory usage problems? compiling with -g and
> using tools like valgrind or gdb may help.

Compiling with -Wall -Wextra -pedantic might also give some hints (although,
since fltk is broken by design in some regards, it may give too much
information)

Regards,
Julien

Phil Malin-3

Re: Funny issue with deleting an external C++ object.

Reply Threaded More More options
Print post
Permalink
Some javascript/style in this post has been disabled (why?)
Hi all.

Thanks for the responses.  I've been able to narrow down where the problem lies and either I've forgotten more C++ than I've learnt, there's a bug in gcc or C++'s inheritance/polymorphism implementation is so bad it's not funny.

I need to waffle on a bit here so hopefully you'll be able to bear with me.

Here's a diagram of part of my setup (needs a monospaced font):

   FLTK             C++ Binding Classes        Eiffel Classes
---------------------------------------------------------------

              (inherit)             ----------->
  Rectangle<|-------------BRectangle<----------- RECTANGLE
     ^                                             ^
     |         (inherit)                           |
  Widget<|----------------BWidget--------------->WIDGET
                                 <---------------


So, my Eiffel widget hierarchy has the same inheritance hierarchy as the FLTK one.  I use (what I call) binding classes which inherit from each FLTK class. These allow me to have the FLTK callbacks and other routines easily call the Eiffel ones (hence the references between the Eiffel class and the corresponding binding class).  There is no relationship between the different binding classes.

Here's the issue:  when I make an external call to the binding object from an Eiffel one I use the FLTK type rather than the binding class type.  E.g.

set(ptr : POINTER;x : INTEGER) is
   external
      "[
         C++ [ fltk::Rectangle "<fltk/Rectangle>" ] (int)
      "]
   alias "set_x"
   end

The reason I do this is so that WIDGET can reuse, via inheritance, the external calls from RECTANGLE since a BWidget is a type of Widget is a type of Rectangle.  If I used BRectangle in the above external call definition then I'd have to redefine it in each subsequent RECTANGLE descendent and use the correct binding class type.

I had a look at the generated C++ and the above seems to produce valid C++ (or at least I think so) as it simply casts my void* reference as a fltk::Rectangle.

The problem is that when I do this for methods which update the C++ object I get a segmentation violation when I eventually delete it (when deleting the void* pointer is correctly cast to its binding object type).  If 'void *ptr' is pointing to a BWidget, then a call like '((fltk::Rectangle*)ptr)->update_method(...)' seems to corrupt 'ptr' even though it has had the desired outcome of the method call.  E.g. setting a width does seem to set it.

I would have thought the above C++ is valid.  I can circumvent this by redefining each inherited external method in my Eiffel widget hieraarchy (I only need to do it once in my framework) but it's pretty ugly and I'd really like to know why the above isn't valid C++ when it seems pretty reasonable.

Thanks for any help/pointers.  I hope the above made sense.

Phil.



Julien Blanc wrote:
On Wed, Feb 4, 2009 at 10:03 PM, Phil Malin [hidden email] wrote:
    
Hi all.

I've got a weird problem that I'm hoping someone's seen before and has some
helpful suggestions.

I'm writing a program which links to a C++ library (FLTK).  The problem has
to do with the destruction of referenced C++ objects - basically I get a
'Received signal 11' error (segmentation violation) when it tries to delete
the C++ object (I've traced it to the actual delete call).  I have no
problem with creating the C++ object and accessing methods on it, only when
it comes to deleting it.  I wondered if it had to do with me casting the
void* to the appropriate type but since accessing other methods work and
they do the same thing re casting, I can't see how this is the problem
(given my basic knowledge of C++).
      

If you cast your pointer to/from void*, you should always make sure you do the
same casts, in reverse order. This is a common mistake, and it especially
doesn't work when dealing with multiple inheritance. (ie, even if B inherits
from A, dont do the following : (A*)((void*)(new B())).

Also, make sure you don't delete it twice.

Deleting void* is undefined behaviour.

Deleting anything that has not been created by new is undefined behaviour.

  
Things that I think may be related:
 are you using "delete" instead of "delete[]" ?
    

new -> delete
new[] -> delete[]

  
 have you got any other memory usage problems? compiling with -g and
using tools like valgrind or gdb may help.
    

Compiling with -Wall -Wextra -pedantic might also give some hints (although,
since fltk is broken by design in some regards, it may give too much
information)

Regards,
Julien


  

Julien Blanc-2

Re: Funny issue with deleting an external C++ object.

Reply Threaded More More options
Print post
Permalink
>          Hi all.
>
> The problem is that when I do this for methods which update the C++
> object I get a segmentation violation when I eventually delete it (when
> deleting the void* pointer is correctly cast to its binding object
> type).  If 'void *ptr' is pointing to a BWidget, then a call like
> '((fltk::Rectangle*)ptr)->update_method(...)' seems to corrupt 'ptr'
> even though it has had the desired outcome of the method call.  E.g.
> setting a width does seem to set it.

From what i understant. BWidget inherits from Widget. Rectangle inherits from
Widget. But since fltk::Rectangle does not inherit from BWidget, doing a
(fltk::Rectangle*)ptr is much likely to not work.

To avoid such casting issues, you should use, whenever possible,
static_cast<fltk::Rectangle>(ptr). At least, you will get a compiler error in
some cases.

Casting to void* is a broken feature, inherited from C. Fltk leaves you no
choice than using it, but you should be extremely cautious with it. Wrapping
your objects in a boost::any structure before passing them to fltk might help
you.

Regards,

Julien

Phil Malin-3

Re: Funny issue with deleting an external C++ object.

Reply Threaded More More options
Print post
Permalink
Some javascript/style in this post has been disabled (why?)
Hi Julien.

Julien Blanc wrote:
         Hi all.

The problem is that when I do this for methods which update the C++
object I get a segmentation violation when I eventually delete it (when
deleting the void* pointer is correctly cast to its binding object
type).&nbsp; If 'void *ptr' is pointing to a BWidget, then a call like
'((fltk::Rectangle*)ptr)-&gt;update_method(...)' seems to corrupt 'ptr'
even though it has had the desired outcome of the method call.&nbsp; E.g.
setting a width does seem to set it.
    

>From what i understant. BWidget inherits from Widget. Rectangle inherits from
Widget. But since fltk::Rectangle does not inherit from BWidget, doing a
(fltk::Rectangle*)ptr is much likely to not work.
  
Actually, BWidget inherits from Widget and Widget inherits from Rectangle, which is why I'm confused that the casting causes grief.  The weird thing is that casting to make a call seems to work (the values that I update get updated as you would expect) - it's only when I go to eventually delete my object that the problem rears its head.

To avoid such casting issues, you should use, whenever possible,
static_cast<fltk::Rectangle>(ptr). At least, you will get a compiler error in
some cases.
  
I tried putting the above in the external part of the Eiffel method but the compiler complained.  I suppose I could create a large C++ class of mapping functions which could be used by every widget class of mine (assuming gcc is happy with the above).  It's not pretty but then I'm sorta beyond that now.  :-)

Casting to void* is a broken feature, inherited from C. Fltk leaves you no
choice than using it, but you should be extremely cautious with it. Wrapping
your objects in a boost::any structure before passing them to fltk might help
you.

Regards,

Julien
  

Thanks for the help.

Cheers,
Phil.