DAMAGE: after Normal block (#45)

Discussion in 'C++' started by Meghavvarnam, May 16, 2005.

  1. Meghavvarnam

    Meghavvarnam Guest

    Hi all,

    I just joined this group and am new to VC++. I wrote the code following
    the next para in C++ and used VC++ 6.0 Enterprise Edition to build and
    test.

    I had the following error message because of an exception that gets
    thrown when I call delete [] ipAddress; in the destructor -
    ~TrapDestination () :

    "DAMAGE: after Normal block (#45)"

    // ~~~~~~~~~~~
    // plugIn.h
    // ~~~~~~~~~~~
    #include <memory>
    #include <iostream>
    #include <exception>
    #include <assert.h>
    using namespace std;

    typedef char* pchar;

    class TrapDestination {
    private:
    pchar ipAddress;
    int port;
    pchar communityName;
    int snmpVersion;
    pchar templateFileName;
    void (*old_unexpected) ();

    public:
    TrapDestination () : ipAddress (NULL), communityName (NULL),
    templateFileName (NULL) { //old_unexpected =
    set_unexpected:):my_unexpected­);
    }
    ~TrapDestination () throw () {
    cout << "TrapDestination Destructor" << endl;
    if (ipAddress)
    delete [] ipAddress;
    if (communityName)
    delete [] communityName;
    if (templateFileName)
    delete [] templateFileName;

    //set_unexpected(old_unexpecte­d); // restore org
    handler
    if (uncaught_exception())
    cout << "uncaught_exception() is TRUE" << endl;

    else
    cout << "uncaught_exception() is FALSE" <<
    endl;
    }

    char *getIPAddress () throw () { return ipAddress; }
    int getPort () throw () { return port; }
    char *getcommunityName () throw () { return communityName; }
    int getsnmpVersion () throw () { return snmpVersion; }
    char *gettemplateFileName () throw () { return
    templateFileName; }

    void setIPAddress (char *ipAddr="") throw () {
    ipAddress = (pchar) new char(strlen (ipAddr) + 1);
    if (ipAddress)
    strcpy (ipAddress, ipAddr);
    }

    void setPort (int aPort=162) { port = aPort; }

    void setcommunityName (char *aCommunityName="public") {
    communityName = (pchar) new char (strlen
    (aCommunityName) + 1);
    if (communityName)
    strcpy (communityName, aCommunityName);
    }

    void setsnmpVersion (int snmpVer=2) { snmpVersion = snmpVer; }

    void settemplateFileName (char *templFileName="") {
    templateFileName = (pchar) new char (strlen
    (templFileName) + 1);
    if (templateFileName)
    strcpy (templateFileName, templFileName);
    }
    };

    class SnmpTrapGen {
    private:
    char *ipAddress;
    int port;
    char *community;
    int snmpVersion;
    public:
    SnmpTrapGen (char *ipAddress=NULL, int port=162, char
    *community="public", int snmpVersion=2){
    }
    ~SnmpTrapGen () {
    if (ipAddress)
    delete [] ipAddress;
    if (community)
    delete [] community;
    }

    sendTrap (char *alertToSend);
    char *getIPAddress () { return ipAddress; }
    int getPort () { return port; }
    char *getcommunity () { return community; }
    int getsnmpVersion () { return snmpVersion; }

    void setIPAddress (char *ipAddr="") {
    ipAddress = new char (strlen (ipAddr) + 1);
    if (ipAddress)
    strcpy (ipAddress, ipAddr);
    }
    void setPort (int aPort=162) { port = aPort; }
    void setcommunity (char *aCommunity="public") {
    community = new char (strlen (aCommunity) + 1);
    if (community)
    strcpy (community, aCommunity);
    }
    void setsnmpVersion (int snmpVer=2) { snmpVersion = snmpVer; }

    };


    // ~~~~~~~~~~~~
    // plugIn.cpp
    // ~~~~~~~~~~~~

    #include "net-snmp\net-snmp-config.h"
    #include "net-snmp\net-snmp-includes.h"
    #include "plugIn.h"

    void local_terminator() {
    cout << "terminate called local_terminator !!!" << endl;
    exit(1);
    }

    void (*old_terminate)();

    void my_unexpected () {
    // This cannot return - instead it can either call std::terminate() or
    throw an exception

    cout << "Am in my_unexpected " << endl;
    }

    int main (int argc, char **argv) {
    try {
    TrapDestination td;

    old_terminate = set_terminate(local_terminator­);
    td.setIPAddress ("127.0.0.1");
    td.setcommunityName ();
    td.settemplateFileName ("tempname");
    cout << "IP address = " << td.getIPAddress () << endl;
    printf ("communityName = %s.\n", td.getcommunityName
    ());
    printf ("templateFileName = %s.\n",
    td.gettemplateFileName ());
    return 0;
    } catch (bad_exception const &) {
    printf("Caught bad_exception\n"); // though such an
    exception was
    never thrown
    return 0;
    } catch (...) {
    cout << "Inside main's catch all" << endl;
    return 0;
    }
    }


    Any light on :

    1. Why is delete causing this exception to be thrown could be helpful.
    2. What the solution for this is.

    will be great!

    Just to add, an earlier post similar to this scenario had a response
    that while allocating space for a string using new, make sure you add 1
    for the '\0'. However I have taken care of doing that in my code and
    yet I have this exception when it hits the delete.

    I really need help from an expert.

    Thank you,
    Meghavvarnam Satish
     
    Meghavvarnam, May 16, 2005
    #1
    1. Advertising

  2. Meghavvarnam wrote:
    > I just joined this group and am new to VC++. I wrote the code following
    > the next para in C++ and used VC++ 6.0 Enterprise Edition to build and
    > test.


    Unless the behaviour is specific to that compiler and you tried other ones
    and found that out, the compiler you used is irrelevant. We don't discuss
    products here. We discuss the language.

    > I had the following error message because of an exception that gets
    > thrown when I call delete [] ipAddress; in the destructor -
    > ~TrapDestination () :
    >
    > "DAMAGE: after Normal block (#45)"
    > [...]


    This is usually caused by memory overrun (writing beyond the bounds of
    an array) or by using an uninitialised pointer (which by coincidence just
    points to some real memory). Use a memory debugging tool (something like
    BoundsChecker or Purify or Insure++) to find the problem, or do it in the
    debugger, manually. Your goal is to learn your tools, not to use this
    newsgroup as your remote debugger.

    V
     
    Victor Bazarov, May 16, 2005
    #2
    1. Advertising

  3. Meghavvarnam

    John Carson Guest

    "Meghavvarnam" <> wrote in message
    news:

    [snip]
    > void setIPAddress (char *ipAddr="") throw () {
    > ipAddress = (pchar) new char(strlen (ipAddr) + 1);
    > if (ipAddress)
    > strcpy (ipAddress, ipAddr);
    > }



    The syntax for new is wrong (here and everywhere else that you use it). It
    should be

    ipAddress = new char[strlen (ipAddr) + 1];

    i.e., use square brackets, not round brackets (your cast to pchar is
    redundant, but that is not what is causing the problem). Square brackets
    give an array of chars, which is what you want. Round brackets are for when
    you are specifying the argument for the constructor of a single object.

    --
    John Carson
     
    John Carson, May 16, 2005
    #3
  4. Meghavvarnam

    CI Guest

    You could try to use auto_ptr rather than using raw pointers. I dont
    see any specific reason why you want to use raw pointer here.
    Ik
     
    CI, May 16, 2005
    #4
  5. Meghavvarnam

    Meghavvarnam Guest

    Hey John!

    I tried your suggestion. And made changes where ever I call new for the
    character pointers.

    It worked fine this time around!!! Thank you so much !!! :)

    I infact looked back into "The C++ Pragraming Language" Third Edition
    by Bjarne Stroustup, pg. 131 where he says for a built in type T, T(e)
    is equivalent to (T) e ; e being any value. This implies that "for
    built-in types", T(e) is not safe.

    So my earlier code -
    ipAddress = (pchar) new char (strlen (ipAddr) + 1);
    was actually looked at as
    ipAddress = (pchar) new (char) strlen (ipAddr) + 1;

    Thus resulting in an int being type casted to a char and then being
    passed to new. And thus we had an implementation defined behaviour over
    there.

    Thanks a lot again!!!
    Megh
     
    Meghavvarnam, May 16, 2005
    #5
  6. Meghavvarnam

    Meghavvarnam Guest

    Hi,

    My original code had auto_ptr instead of a plain char *.

    However when I debugged and looked at the call stack, the destructor
    would call delete. delete would then call free. free would then call
    _free_dbg. And then I would get that exception.

    I doubted auto_ptr and to make it simpler, I used char *. However as
    you all know now, the behaviour did not change.

    However now I will use auto_ptr and see how it behaves. We wont need to
    call delete at that point of time specifically, because our friend
    auto_ptr would do that for us.

    Will be back with the update folks !

    Thank you!
    Megh
     
    Meghavvarnam, May 16, 2005
    #6
  7. Meghavvarnam wrote:
    > My original code had auto_ptr instead of a plain char *.
    >
    > However when I debugged and looked at the call stack, the destructor
    > would call delete. delete would then call free. free would then call
    > _free_dbg. And then I would get that exception.
    >
    > I doubted auto_ptr and to make it simpler, I used char *. However as
    > you all know now, the behaviour did not change.
    >
    > However now I will use auto_ptr and see how it behaves. We wont need to
    > call delete at that point of time specifically, because our friend
    > auto_ptr would do that for us.
    >
    > Will be back with the update folks !


    'auto_ptr' is not going to work for you. It does NOT work with arrays.
    And you apparently need arrays.

    Stop using the array of char and switch to 'std::string'.

    V
     
    Victor Bazarov, May 16, 2005
    #7
  8. Meghavvarnam

    Meghavvarnam Guest

    Hi again,

    Below is the auto_ptr version. It works fine too !!! :)

    // ~~~~~~~~
    // plugIn.h
    // ~~~~~~~~

    #include <memory>
    #include <iostream>
    #include <exception>
    #include <assert.h>
    using namespace std;

    typedef auto_ptr <char> pchar;

    //typedef char* pchar;

    class TrapDestination {
    private:
    pchar ipAddress;
    int port;
    pchar communityName;
    int snmpVersion;
    pchar templateFileName;
    void (*old_unexpected) ();

    public:
    TrapDestination () : ipAddress (NULL), communityName (NULL),
    templateFileName (NULL) {
    }
    ~TrapDestination () throw () {
    cout << "TrapDestination Destructor" << endl;
    //set_unexpected(old_unexpected); // restore org handler
    if (uncaught_exception())
    cout << "uncaught_exception() is TRUE" << endl;
    else
    cout << "uncaught_exception() is FALSE" << endl;
    }

    char *getIPAddress () throw () { return ipAddress.get (); }
    int getPort () throw () { return port; }
    char *getcommunityName () throw () { return communityName.get (); }
    int getsnmpVersion () throw () { return snmpVersion; }
    char *gettemplateFileName () throw () { return templateFileName.get
    (); }

    void setIPAddress (char *ipAddr="") throw () {
    ipAddress = (pchar) new char [strlen (ipAddr) + 1];
    if (ipAddress.get ())
    strcpy (ipAddress.get (), ipAddr);
    ipAddress.get ()[strlen(ipAddr)] = '\0';
    }

    void setPort (int aPort=162) { port = aPort; }

    void setcommunityName (char *aCommunityName="public") {
    communityName = (pchar) new char [strlen (aCommunityName) + 1];
    if (communityName.get ())
    strcpy (communityName.get (), aCommunityName);
    }

    void setsnmpVersion (int snmpVer=2) { snmpVersion = snmpVer; }

    void settemplateFileName (char *templFileName="") {
    templateFileName = (pchar) new char [strlen (templFileName) + 1];
    if (templateFileName.get ())
    strcpy (templateFileName.get (), templFileName);
    }
    };


    class SnmpTrapGen {
    private:
    char *ipAddress;
    int port;
    char *community;
    int snmpVersion;
    public:
    SnmpTrapGen (char *ipAddress=NULL, int port=162, char
    *community="public", int snmpVersion=2){
    }
    ~SnmpTrapGen () {
    if (ipAddress)
    delete [] ipAddress;
    if (community)
    delete [] community;
    }

    sendTrap (char *alertToSend);

    char *getIPAddress () { return ipAddress; }
    int getPort () { return port; }
    char *getcommunity () { return community; }
    int getsnmpVersion () { return snmpVersion; }

    void setIPAddress (char *ipAddr="") {
    ipAddress = new char [strlen (ipAddr) + 1];
    if (ipAddress)
    strcpy (ipAddress, ipAddr);
    }
    void setPort (int aPort=162) { port = aPort; }
    void setcommunity (char *aCommunity="public") {
    community = new char [strlen (aCommunity) + 1];
    if (community)
    strcpy (community, aCommunity);
    }
    void setsnmpVersion (int snmpVer=2) { snmpVersion = snmpVer; }
    };
     
    Meghavvarnam, May 16, 2005
    #8
  9. Meghavvarnam

    Meghavvarnam Guest

    Hi all:

    Apologies for the confusion in my previous post. Am pasting the above
    piece of code that works again. Have reformatted it.

    Please note the usage of the member function get () to get the address
    of an auto_ptr variable.

    // ~~~~~~~~~
    // plugIn.h
    // ~~~~~~~~~

    #include <memory>
    #include <iostream>
    #include <exception>
    #include <assert.h>
    using namespace std;

    typedef auto_ptr <char> pchar;

    class TrapDestination {
    private:
    pchar ipAddress;
    int port;
    pchar communityName;
    int snmpVersion;
    pchar templateFileName;
    void (*old_unexpected) ();

    public:
    TrapDestination () : ipAddress (NULL), communityName (NULL),
    templateFileName (NULL) {
    //old_unexpected = set_unexpected:):my_unexpected);
    }
    ~TrapDestination () throw () {
    cout << "TrapDestination Destructor" << endl;

    if (uncaught_exception())
    cout << "uncaught_exception() is TRUE" << endl;
    else
    cout << "uncaught_exception() is FALSE" << endl;
    }

    char *getIPAddress () throw () { return ipAddress.get (); }
    int getPort () throw () { return port; }
    char *getcommunityName () throw () { return communityName.get (); }
    int getsnmpVersion () throw () { return snmpVersion; }
    char *gettemplateFileName () throw () { return templateFileName.get
    (); }

    void setIPAddress (char *ipAddr="") throw () {
    ipAddress = (pchar) new char [strlen (ipAddr) + 1];
    if (ipAddress.get ())
    strcpy (ipAddress.get (), ipAddr);
    ipAddress.get ()[strlen(ipAddr)] = '\0';
    }

    void setPort (int aPort=162) { port = aPort; }

    void setcommunityName (char *aCommunityName="public") {
    communityName = (pchar) new char [strlen (aCommunityName) + 1];
    if (communityName.get ())
    strcpy (communityName.get (), aCommunityName);
    }

    void setsnmpVersion (int snmpVer=2) { snmpVersion = snmpVer; }

    void settemplateFileName (char *templFileName="") {
    templateFileName = (pchar) new char [strlen (templFileName) + 1];
    if (templateFileName.get ())
    strcpy (templateFileName.get (), templFileName);
    }

    };


    class SnmpTrapGen {
    private:
    char *ipAddress;
    int port;
    char *community;
    int snmpVersion;
    public:
    SnmpTrapGen (char *ipAddress=NULL, int port=162, char
    *community="public", int snmpVersion=2){
    }
    ~SnmpTrapGen () {
    if (ipAddress)
    delete [] ipAddress;
    if (community)
    delete [] community;
    }

    sendTrap (char *alertToSend);

    char *getIPAddress () { return ipAddress; }
    int getPort () { return port; }
    char *getcommunity () { return community; }
    int getsnmpVersion () { return snmpVersion; }

    void setIPAddress (char *ipAddr="") {
    ipAddress = new char [strlen (ipAddr) + 1];
    if (ipAddress)
    strcpy (ipAddress, ipAddr);
    }
    void setPort (int aPort=162) { port = aPort; }
    void setcommunity (char *aCommunity="public") {
    community = new char [strlen (aCommunity) + 1];
    if (community)
    strcpy (community, aCommunity);
    }
    void setsnmpVersion (int snmpVer=2) { snmpVersion = snmpVer; }

    };

    Thank you again
    Megh
     
    Meghavvarnam, May 16, 2005
    #9
  10. Meghavvarnam

    Meghavvarnam Guest

    Hi V,

    When we declare, we use auto_ptr. As you might already know, auto_ptr
    is a mechanism that provides ownership to take care of releasing the
    memory that we allocate with a new.

    However, while calling new, specifically for an inbuilt type, we
    specify the size of memory that we request with in square brackets.

    And once the memory is allocated, we could use it like an array. We
    could index into it too.

    Anyway thanks for your suggestion about the 'std::string'

    Regards,
    Megh
     
    Meghavvarnam, May 16, 2005
    #10
  11. Meghavvarnam wrote:
    > When we declare, we use auto_ptr. As you might already know, auto_ptr
    > is a mechanism that provides ownership to take care of releasing the
    > memory that we allocate with a new.
    >
    > However, while calling new, specifically for an inbuilt type, we
    > specify the size of memory that we request with in square brackets.
    >
    > And once the memory is allocated, we could use it like an array. We
    > could index into it too.


    That would be wrong. 'auto_ptr' destroys the object using 'delete'.
    If you allocate it using 'new[]', you _have_to_ use 'delete[]' and not
    'delete'. So, 'auto_ptr' is not a suitable mechanism here.

    > [...]


    V
     
    Victor Bazarov, May 16, 2005
    #11
  12. Meghavvarnam wrote:
    > Apologies for the confusion in my previous post. Am pasting the above
    > piece of code that works again. Have reformatted it.
    >
    > Please note the usage of the member function get () to get the address
    > of an auto_ptr variable.
    > [...]


    Your code has undefined behaviour. If it happens to work on your
    system, it's no indication that it's correct.

    V
     
    Victor Bazarov, May 16, 2005
    #12
    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. davidw
    Replies:
    3
    Views:
    426
    Curt_C [MVP]
    Aug 27, 2004
  2. Content Damage

    , Sep 13, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    1,197
  3. Thomas Adams
    Replies:
    0
    Views:
    812
    Thomas Adams
    Feb 12, 2005
  4. Anuradha

    malloc->free->damage: after normal block

    Anuradha, Aug 25, 2004, in forum: C Programming
    Replies:
    6
    Views:
    633
    Thomas Rogg
    Sep 3, 2004
  5. Meghavvarnam

    DAMAGE: after Normal block (#45)

    Meghavvarnam, May 16, 2005, in forum: C Programming
    Replies:
    5
    Views:
    522
    CBFalconer
    May 16, 2005
Loading...

Share This Page