C++ delete throwing exception

Discussion in 'C++' started by John Fullman, Sep 12, 2005.

  1. John  Fullman

    John Fullman Guest

    I have an application with a class that just doesn't seem to like
    destroying...

    I have a member that is stored on the heap and it is deleted in the
    destructor.

    When I run the app in debug mode, I break at the destructor and the
    member is still active on the heap. When I step through the delete, it
    throws an exception saying that there's nothin' to delete. Wierd.

    If it's worth anything, the class in question is imported from another
    DLL using __declspec(import) and is cannonical (ie. has a default
    constructor, copy constructor, = operator, and destructor)

    Has anyone seen this behavior before or am I just doing something wierd
    in my code somewhere that I don't see???
     
    John Fullman, Sep 12, 2005
    #1
    1. Advertising

  2. John  Fullman

    Jim Langston Guest

    "John Fullman" <> wrote in message
    news:...
    >I have an application with a class that just doesn't seem to like
    > destroying...
    >
    > I have a member that is stored on the heap and it is deleted in the
    > destructor.
    >
    > When I run the app in debug mode, I break at the destructor and the
    > member is still active on the heap. When I step through the delete, it
    > throws an exception saying that there's nothin' to delete. Wierd.
    >
    > If it's worth anything, the class in question is imported from another
    > DLL using __declspec(import) and is cannonical (ie. has a default
    > constructor, copy constructor, = operator, and destructor)
    >
    > Has anyone seen this behavior before or am I just doing something wierd
    > in my code somewhere that I don't see???
    >


    Hard to say without seeing the class.
     
    Jim Langston, Sep 12, 2005
    #2
    1. Advertising

  3. John  Fullman

    John Fullman Guest

    class dllobject_mb RuleItem
    {
    public:
    RuleItem();
    RuleItem(Event* ev);
    RuleItem(NonTerminal* nt);
    RuleItem(Token* t);

    RuleItem(const RuleItem& copy);
    RuleItem& operator=(const RuleItem& copy);
    ~RuleItem();

    NonTerminal* NonTerminalRef;
    Token* TokenRef;
    Event* EventRef;

    bool IsToken();
    bool IsEvent();
    bool IsNonTerminal();

    JFC::String ToString();
    bool operator==(const RuleItem& operand) const;
    bool operator>(const RuleItem& operand) const;
    };
    }}


    //Destructor Code:
    RuleItem::~RuleItem()
    {
    if(EventRef != 0)
    delete EventRef;
    EventRef = 0;
    if(TokenRef != 0)
    delete TokenRef;
    TokenRef = 0;
    NonTerminalRef = 0;
    }


    My members are public, but I tested the scenario with this code:
    RuleItem* tok = new RuleItem(new Token(0, "fdsf"));
    delete tok;
    and that kills it somehow. The constructors do only what you'd expect.
     
    John Fullman, Sep 12, 2005
    #3
  4. John Fullman wrote:
    > class dllobject_mb RuleItem
    > {
    > public:
    > RuleItem();
    > RuleItem(Event* ev);
    > RuleItem(NonTerminal* nt);
    > RuleItem(Token* t);
    >
    > RuleItem(const RuleItem& copy);
    > RuleItem& operator=(const RuleItem& copy);
    > ~RuleItem();
    >
    > NonTerminal* NonTerminalRef;
    > Token* TokenRef;
    > Event* EventRef;
    >
    > bool IsToken();
    > bool IsEvent();
    > bool IsNonTerminal();
    >
    > JFC::String ToString();
    > bool operator==(const RuleItem& operand) const;
    > bool operator>(const RuleItem& operand) const;
    > };
    > }}
    >
    >
    > //Destructor Code:
    > RuleItem::~RuleItem()
    > {
    > if(EventRef != 0)
    > delete EventRef;
    > EventRef = 0;
    > if(TokenRef != 0)
    > delete TokenRef;
    > TokenRef = 0;
    > NonTerminalRef = 0;
    > }


    This can be simplified, it's OK to delete 0, and obviously the values of
    your memory variable don't matter after the destructor has exitted.

    RuleItem::~RuleItem()
    {
    delete EventRef;
    delete TokenRef;
    }

    >
    >
    > My members are public, but I tested the scenario with this code:
    > RuleItem* tok = new RuleItem(new Token(0, "fdsf"));
    > delete tok;
    > and that kills it somehow. The constructors do only what you'd expect.
    >


    Well the only thing missing is the constructor code. Possibly the error
    is in there. As Jim says it's hard to fix coding errors without seeing
    the code.

    You mentioned DLLs, you do realise that it is not possible to allocate
    memory in a DLL and then free it in the main program (or another DLL).
    In other words each DLL has it's own heap, and you can't mix them up. I
    think that would be the first place to look.

    john
     
    John Harrison, Sep 12, 2005
    #4
  5. John  Fullman

    John Fullman Guest

    Thanks John! That is my problem exactly!

    I am newing mem in the main app and deleting from the dll.
    This is a design flaw that I didn't account for in multiple locations.

    This does, however, draw out another problem....

    I have a dll-imported class with a templated array member. This means,
    when I call the LinkedList<Token>::Add() function from application
    space, it is newed in application space. Then, it is destroyed in dll
    space, because it belongs to a dll imported class. The solution seems
    to be that I need to cause the templated collection to be pre-compiled
    in dll space.
    If I do the following in my dll:

    class TokenList : public LinkedList<Token>
    {
    };

    and use the TokenList as the member, will that fix the problem?

    Thanks.
     
    John Fullman, Sep 12, 2005
    #5
  6. John Fullman wrote:
    > Thanks John! That is my problem exactly!
    >
    > I am newing mem in the main app and deleting from the dll.
    > This is a design flaw that I didn't account for in multiple locations.
    >
    > This does, however, draw out another problem....
    >
    > I have a dll-imported class with a templated array member. This means,
    > when I call the LinkedList<Token>::Add() function from application
    > space, it is newed in application space. Then, it is destroyed in dll
    > space, because it belongs to a dll imported class. The solution seems
    > to be that I need to cause the templated collection to be pre-compiled
    > in dll space.
    > If I do the following in my dll:
    >
    > class TokenList : public LinkedList<Token>
    > {
    > };
    >
    > and use the TokenList as the member, will that fix the problem?
    >
    > Thanks.
    >


    This is getting a bit beyond my expertise. I know about the DLL memory
    allocation problem but not in detail how to fix it or work around it.
    Best bet is to try a microsoft group, perhaps
    news:microsoft.public.vc.language.

    john
     
    John Harrison, Sep 12, 2005
    #6
  7. John  Fullman

    Old Wolf Guest

    John Harrison wrote:
    >
    > You mentioned DLLs, you do realise that it is not possible to
    > allocate memory in a DLL and then free it in the main program
    > (or another DLL). In other words each DLL has it's own heap,
    > and you can't mix them up. I think that would be the first place
    > to look.


    I believe you can mix them up as long as you ensure they are both
    using the same C runtime library (which wouldn't happen if one were
    built in release mode and one in debug mode, for example), because
    once a DLL is loaded, it just becomes part of the current process.
     
    Old Wolf, Sep 12, 2005
    #7
  8. John  Fullman

    Shezan Baig Guest

    John Fullman wrote:
    > Thanks John! That is my problem exactly!
    >
    > I am newing mem in the main app and deleting from the dll.
    > This is a design flaw that I didn't account for in multiple locations.
    >
    > This does, however, draw out another problem....
    >
    > I have a dll-imported class with a templated array member. This means,
    > when I call the LinkedList<Token>::Add() function from application
    > space, it is newed in application space. Then, it is destroyed in dll
    > space, because it belongs to a dll imported class. The solution seems
    > to be that I need to cause the templated collection to be pre-compiled
    > in dll space.



    You could try using an allocator as an extra level of indirection,
    instead of using global 'new' and 'delete' directly. (This is also
    considered a good practice, to allow clients to pass in any allocator
    they want.)

    Hope this helps,
    -shez-
     
    Shezan Baig, Sep 12, 2005
    #8
  9. John  Fullman

    John Fullman Guest

    Well all my components are compiled in Dubug mode and I have certainly
    found this mixing up heaps deal to be the problem.

    I am not sure if I want to go as far as to write an allocator class...
    as a last resort, maybe... Too many layers of abstraction scare me :p
     
    John Fullman, Sep 13, 2005
    #9
  10. John  Fullman

    John Fullman Guest

    Hey all... well I found a viable solution to the problem and it looks
    like I was on the right track with the inheritance thing:

    class __declspec(import) TokenList : public LinkedList<Token> {};

    As long as I make sure the class gets exported, it forces all the
    members of the template to be compiled into the dll.. and walla!!..
    everything is allocated in dll-space...

    Thanks to everyone who contributed.... You guys have been really
    helpful :)
    I'll be sure to jump back to this forum whenever I get a chance and
    help you guys out once in a while :)
     
    John Fullman, Sep 13, 2005
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. KJ
    Replies:
    5
    Views:
    388
    John Saunders
    Jul 25, 2003
  2. VincentWong
    Replies:
    1
    Views:
    582
    VincentWong
    Dec 29, 2003
  3. =?Utf-8?B?VGVycnk=?=
    Replies:
    4
    Views:
    6,048
    =?Utf-8?B?VGVycnk=?=
    Jan 13, 2005
  4. =?Utf-8?B?R2xlbm4gVmVuemtl?=

    System.IO.Directoryinfo throwing exception

    =?Utf-8?B?R2xlbm4gVmVuemtl?=, Jul 25, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    3,728
    John Timney \(ASP.NET MVP\)
    Jul 25, 2005
  5. =?Utf-8?B?RXVzdGljZSBTY3J1YmI=?=

    Insert.aspx throwing exception

    =?Utf-8?B?RXVzdGljZSBTY3J1YmI=?=, Sep 23, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    587
    =?Utf-8?B?RXVzdGljZSBTY3J1YmI=?=
    Sep 23, 2005
Loading...

Share This Page