malloc->free->damage: after normal block

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Anuradha

    malloc->free->damage: after normal block

    Below is the code which was written VC++ 6.0 under windows environment.

    Executing the same throws:
    ------------------
    Debug Error!
    Program: ccheck.exe
    DAMAGE: after normal block (#41) at 0x00300160

    (Press Retry to debug the application)
    ------------------


    While the free () statement is commented the program does not report the error.

    Please do let me know your views ...

    Thanks in advance.

    # include <string.h>
    # include <stdio.h>
    # include <stdlib.h>
    # include <errno.h>

    # define _DEBUG_ 1

    void SetProgramName (char *);
    char * GetProgramName ();
    void PrintUsage ();
    void PrintErrMsg (size_t);
    void ClearMemory ();

    char *ProgramName = NULL;

    extern errno;

    int
    main (int argc, char *argv[])
    {
    SetProgramName (argv[0]);

    if (argc < 2)
    {
    PrintUsage ();
    ClearMemory ();
    }

    return (EXIT_SUCCESS);
    }

    void
    SetProgramName (char *PrgName)
    {

    ProgramName = (char *) malloc (strlen (PrgName));

    if (ProgramName == NULL)
    {
    PrintErrMsg (errno);
    }
    else
    {
    (void) strcpy (ProgramName, PrgName);

    #if defined (_DEBUG_)
    (void) fprintf (stderr, "\n Debug: ProgramName %s \n", ProgramName);
    #endif

    }
    }

    char *
    GetProgramName ()
    {
    return (ProgramName == NULL ? NULL : ProgramName);
    }

    void
    ClearMemory ()
    {
    if (strlen (ProgramName) > 0)
    {
    free (ProgramName);
    #if 0
    ProgramName = NULL;
    #endif
    PrintErrMsg (errno);
    }
    }


    void
    PrintErrMsg (size_t ErrNumber)
    {
    (void) fprintf ( stderr, \
    "\n Err Number [%ld] \n Err Msg [%s] \n", \
    ErrNumber, strerror (ErrNumber)
    );
    }

    void
    PrintUsage ()
    {
    (void) fprintf (stderr, "\n %s <> <>", GetProgramName( ));
    }


    ---

    Thanks,
    Anu
  • boa

    #2
    Re: malloc-&gt;free-&gt;damage: after normal block

    Anuradha wrote:
    [color=blue]
    > Below is the code which was written VC++ 6.0 under windows environment.
    >
    > Executing the same throws:
    > ------------------
    > Debug Error!
    > Program: ccheck.exe
    > DAMAGE: after normal block (#41) at 0x00300160
    >
    > (Press Retry to debug the application)
    > ------------------
    >
    >
    > While the free () statement is commented the program does not report the error.
    >
    > Please do let me know your views ...[/color]
    [snip]
    [color=blue]
    > void
    > SetProgramName (char *PrgName)
    > {
    >
    > ProgramName = (char *) malloc (strlen (PrgName));[/color]
    ProgramName = malloc(strlen(P rgName) + 1);


    boa

    [snip]

    Comment

    • Gordon Burditt

      #3
      Re: malloc-&gt;free-&gt;damage: after normal block

      > ProgramName = (char *) malloc (strlen (PrgName));

      You are not allocating enough memory here.
      [color=blue]
      >
      > if (ProgramName == NULL)
      > {
      > PrintErrMsg (errno);
      > }
      > else
      > {
      > (void) strcpy (ProgramName, PrgName);[/color]

      And here you run over memory beyond what you allocated.

      Gordon L. Burditt

      Comment

      • Christian Kandeler

        #4
        Re: malloc-&gt;free-&gt;damage: after normal block

        Anuradha wrote:
        [color=blue]
        > # include <string.h>
        > # include <stdio.h>
        > # include <stdlib.h>
        > # include <errno.h>
        >
        > # define _DEBUG_ 1
        >
        > void SetProgramName (char *);
        > char * GetProgramName ();
        > void PrintUsage ();[/color]

        Better:
        char * GetProgramName (void);
        void PrintUsage (void);
        [color=blue]
        > void PrintErrMsg (size_t);
        > void ClearMemory ();[/color]

        Same here.
        [color=blue]
        > char *ProgramName = NULL;
        >
        > extern errno;[/color]

        It would be a good idea to tell your program about the type of errno.
        [color=blue]
        > int
        > main (int argc, char *argv[])
        > {
        > SetProgramName (argv[0]);
        >
        > if (argc < 2)
        > {
        > PrintUsage ();
        > ClearMemory ();
        > }
        >
        > return (EXIT_SUCCESS);
        > }
        >
        > void
        > SetProgramName (char *PrgName)
        > {
        >
        > ProgramName = (char *) malloc (strlen (PrgName));[/color]

        You need
        ProgramName = malloc (strlen (PrgName) + 1);
        because the '\0' character is not counted by strlen().
        [color=blue]
        >
        > if (ProgramName == NULL)
        > {
        > PrintErrMsg (errno);[/color]

        This is kind of silly, since errno is a global variable anyway.
        [color=blue]
        > }
        > else
        > {
        > (void) strcpy (ProgramName, PrgName);
        >
        > #if defined (_DEBUG_)
        > (void) fprintf (stderr, "\n Debug: ProgramName %s \n", ProgramName);
        > #endif
        >
        > }
        > }
        >
        > char *
        > GetProgramName ()
        > {
        > return (ProgramName == NULL ? NULL : ProgramName);[/color]

        This is equivalent to
        return ProgramName;
        [color=blue]
        > }
        >
        > void
        > ClearMemory ()
        > {
        > if (strlen (ProgramName) > 0)[/color]

        This is not the way to test whether the string allocation was successful.
        You want
        if (ProgramName != NULL)
        [color=blue]
        > {
        > free (ProgramName);
        > #if 0
        > ProgramName = NULL;
        > #endif
        > PrintErrMsg (errno);
        > }
        > }[/color]

        By the way: You don't need to copy argv[0] at all, since it exists until the
        end of the program.


        Christian

        Comment

        • Flash Gordon

          #5
          Re: malloc-&gt;free-&gt;damage: after normal block

          On Thu, 26 Aug 2004 08:53:01 +0200
          Christian Kandeler <christian.kand eler@hob.de> wrote:
          [color=blue]
          > Anuradha wrote:
          >[color=green]
          > > # include <string.h>
          > > # include <stdio.h>
          > > # include <stdlib.h>
          > > # include <errno.h>[/color][/color]

          <snip>
          [color=blue][color=green]
          > > extern errno;[/color]
          >
          > It would be a good idea to tell your program about the type of errno.[/color]

          No it isn't, it's better to delete the "extern errno;" entirely. errno
          is declared appropriately by errno.h

          <snip>
          [color=blue][color=green]
          > > if (ProgramName == NULL)
          > > {
          > > PrintErrMsg (errno);[/color]
          >
          > This is kind of silly, since errno is a global variable anyway.[/color]

          It is silly.

          However, errno might not be a global variable, it could be a macro that
          expands to a modifiable lvalue :-)
          --
          Flash Gordon
          Pedantic to the last, except I sometimes get it wrong.
          Sometimes I think shooting would be far too good for some people.
          Although my email address says spam, it is real and I read it.

          Comment

          • Gordon Burditt

            #6
            Re: malloc-&gt;free-&gt;damage: after normal block

            >>[color=blue][color=green]
            >> if (ProgramName == NULL)
            >> {
            >> PrintErrMsg (errno);[/color]
            >
            >This is kind of silly, since errno is a global variable anyway.[/color]

            No, it's *NOT* silly. It's perfectly possible and reasonable to
            pass something else (for example, a saved version of errno from
            before you tried opening the log file to put the error message in).
            Being forced to save and restore errno is a pain, and so many things
            MIGHT mess it up (such as opening log files, and even printf()),
            it's often necessary. With a function taking an argument, you're
            still sometimes stuck with saving errno, but usually not with
            restoring it.

            It's not that unusual to have a function return an error code or 0
            to indicate success. I see that a lot inside kernels. There, you
            want to deal with what the kernel returned, not errno.

            Why does strerror() take an argument rather than use errno? Same
            issue.

            Gordon L. Burditt

            Comment

            • Thomas Rogg

              #7
              Re: malloc-&gt;free-&gt;damage: after normal block

              Anuradha wrote:
              [color=blue]
              > return (ProgramName == NULL ? NULL : ProgramName);[/color]
              return ProgramName;

              Not an error, though... See the other replys for that.

              -- Thomas

              Comment

              Working...