Impossible Leak realloc

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

    Impossible Leak realloc

    Hi,

    Can any one tell me what's wrong with this code?

    It leaks (acceding to bound checker), when it attempts to reallocate memory.

    The code is not pure C, but with minor adjustments any C compiler would
    compile this.



    Thank you

    Eitan Michaelson.



    ////////////////////////////////////////////////// Code Starts Here
    ///////////////////////////////////////////////////////////////////////



    // This code attempts to create a pointer to a structure,and then allocate a
    buffer for that structure, so it would hold an array of structures.

    // in each loop I’m trying to reallocate the structure array so it would
    grow by 1, and then I'm trying to add data into it.

    // one of the structure elements is a void*, which in turn is allocated by
    malloc.




    #include <stdio.h>
    #include <malloc.h>
    #include <string.h>

    #define MAX_STRUCT_SIZE (50)
    struct st_Test
    {
    char szChar[32];
    int iInt;
    void *pVoid;
    };
    void main(void)
    {
    // Pointer to the structure
    st_Test *pst_Test;
    pst_Test = NULL; // pointer not valid yet
    for(int i = 0;i <=MAX_STRUCT_SI ZE;i++)
    {
    if(!pst_Test) // not yet allocated
    pst_Test = (st_Test*)mallo c(1 * sizeof(st_Test) );
    else // Resize by 1
    pst_Test = (st_Test*)reall oc(pst_Test,(i+ 1)
    *sizeof(st_Test )); /// This is the Leak /////////
    // Reset the buffer we got
    memset(&pst_Tes t[i],'\0',sizeof(st _Test));
    // Add some data to the allocated struct
    pst_Test[i].iInt = 64738;
    strcpy(pst_Test[i].szChar,"poke 53280,1");
    // allocate buffer for the void* element ////// This is
    where bound checker found the problem ///
    if(!pst_Test[i].pVoid)
    pst_Test[i].pVoid = (char*)malloc(3 2);
    strcpy((char*)p st_Test[i].pVoid,"commodr e 64");
    }

    ////////////////////////////////////////////////// End
    ///////////////////////////////////////////////////////////////////////





    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.m oderated. First time posters: Do this! ]
  • Ken Hagan

    #2
    Re: Impossible Leak realloc

    Eitan Michaelson wrote:[color=blue]
    > Hi,
    >
    > Can any one tell me what's wrong with this code?
    >
    > It leaks (acceding to bound checker), when it attempts to reallocate
    > memory.[/color]

    The code you posted never calls free() so presumably everything is
    leaked. You need to free the pVoid members of all the elements and
    then free pst_Text itself.

    (Note: My newsreader couldn't find alt.comp.lang.c so I've dropped it.)



    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.m oderated. First time posters: Do this! ]

    Comment

    • Andy Sawyer

      #3
      Re: Impossible Leak realloc

      In article <bdgrml$drf$1@n ews2.netvision. net.il>,
      on 27 Jun 2003 07:01:37 -0400,
      Eitan Michaelson <m_eitan@netvis ion.net.il> wrote:
      [color=blue]
      > Hi,
      >
      > Can any one tell me what's wrong with this code?
      >
      > It leaks (acceding to bound checker), when it attempts to reallocate
      > memory.[/color]

      There isn't a single call to free in your code, so of course it leaks.

      --
      "Light thinks it travels faster than anything but it is wrong. No matter
      how fast light travels it finds the darkness has always got there first,
      and is waiting for it." -- Terry Pratchett, Reaper Man

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.m oderated. First time posters: Do this! ]

      Comment

      • CBFalconer

        #4
        Re: Impossible Leak realloc

        Eitan Michaelson wrote:[color=blue]
        >
        > Can any one tell me what's wrong with this code?
        >
        > It leaks (acceding to bound checker), when it attempts to
        > reallocate memory.[/color]

        It contains invalid includes <malloc.h> and invalid (for C99, and
        for display in a message) // comment forms. The indentation is
        excessive. You should first convert it to a compilable form, in
        standard C, and then post it. Ensure that lines do not exceed 65
        characters in general, but anything of 80 or more characters does
        not belong in newsgroups.

        Why should we wade through a mess that you have created?

        --
        Chuck F (cbfalconer@yah oo.com) (cbfalconer@wor ldnet.att.net)
        Available for consulting/temporary embedded and systems.
        <http://cbfalconer.home .att.net> USE worldnet address!


        [ See http://www.gotw.ca/resources/clcm.htm for info about ]
        [ comp.lang.c++.m oderated. First time posters: Do this! ]

        Comment

        • Brett Frankenberger

          #5
          Re: Impossible Leak realloc

          In article <bdgrml$drf$1@n ews2.netvision. net.il>,
          Eitan Michaelson <m_eitan@netvis ion.net.il> wrote:[color=blue]
          >
          >#include <stdio.h>
          >#include <malloc.h>
          >#include <string.h>
          >
          >#define MAX_STRUCT_SIZE (50)
          >struct st_Test
          >{
          > char szChar[32];
          > int iInt;
          > void *pVoid;
          >};
          >void main(void)
          >{
          > // Pointer to the structure
          > st_Test *pst_Test;
          > pst_Test = NULL; // pointer not valid yet
          > for(int i = 0;i <=MAX_STRUCT_SI ZE;i++)
          > {
          > if(!pst_Test) // not yet allocated
          > pst_Test = (st_Test*)mallo c(1 * sizeof(st_Test) );
          > else // Resize by 1
          > pst_Test = (st_Test*)reall oc(pst_Test,(i+ 1)
          >*sizeof(st_Tes t)); /// This is the Leak /////////
          > // Reset the buffer we got
          > memset(&pst_Tes t[i],'\0',sizeof(st _Test));
          > // Add some data to the allocated struct
          > pst_Test[i].iInt = 64738;
          > strcpy(pst_Test[i].szChar,"poke 53280,1");
          > // allocate buffer for the void* element ////// This is
          >where bound checker found the problem ///
          > if(!pst_Test[i].pVoid)
          > pst_Test[i].pVoid = (char*)malloc(3 2);[/color]

          Why do you test pst_Test[1].pVoid for NULL before allocating memory for
          it? Neither malloc or realloc makes any guarantees about the contents
          of the memory it allocates. So pst_Test[i].pVoid is unitilialized.
          The act of testing it for NULL in the if statement above is undefined.
          If it happens to be initialized to NULL, then your program will
          probably work; if it happens to be initialized to something else, then
          the if will probably fail and the strcpy below will likely end up
          copying to some random memory location.
          [color=blue]
          > strcpy((char*)p st_Test[i].pVoid,"commodr e 64");
          > }[/color]

          -- Brett (Still remembers what poke 53280,1 does on a Commodore 64)

          [ See http://www.gotw.ca/resources/clcm.htm for info about ]
          [ comp.lang.c++.m oderated. First time posters: Do this! ]

          Comment

          • Dan Pop

            #6
            Re: Impossible Leak realloc

            In <bdgrml$drf$1@n ews2.netvision. net.il> Eitan Michaelson
            <m_eitan@netvis ion.net.il> writes:
            [color=blue]
            >The code is not pure C, but with minor adjustments any C compiler would
            >compile this.[/color]

            Then, why didn't *you* make those minor adjustments, so that any C
            compiler would compile it?

            Don't expect much help when deliberately posting broken C code. Not
            from the C newsgroups, anyway.

            Dan
            --
            Dan Pop
            DESY Zeuthen, RZ group
            Email: Dan.Pop@ifh.de

            [ See http://www.gotw.ca/resources/clcm.htm for info about ]
            [ comp.lang.c++.m oderated. First time posters: Do this! ]

            Comment

            • goose

              #7
              Re: Impossible Leak realloc

              Eitan Michaelson <m_eitan@netvis ion.net.il> wrote in message
              news:<bdgrml$dr f$1@news2.netvi sion.net.il>...[color=blue]
              > Hi,
              >
              > Can any one tell me what's wrong with this code?
              >
              > It leaks (acceding to bound checker), when it attempts to reallocate[/color]
              memory.[color=blue]
              >
              > The code is not pure C, but with minor adjustments any C compiler[/color]
              would[color=blue]
              > compile this.[/color]

              you know this and yet you still post ?
              <grin>
              heathen!!!

              seriously, make it "pure C" and repost ... I'm sure that a lot more
              people will look at it then ...

              <snipped>
              [color=blue]
              >
              > #include <stdio.h>
              > #include <malloc.h>[/color]

              I dont know why you include malloc.h
              [color=blue]
              > #include <string.h>
              >
              > #define MAX_STRUCT_SIZE (50)
              > struct st_Test
              > {
              > char szChar[32];
              > int iInt;
              > void *pVoid;
              > };
              > void main(void)[/color]

              its supposed to be
              int main (void)
              [color=blue]
              > {
              > // Pointer to the structure[/color]

              comments of this form are illegal, use
              /* comments like this */ (unless you are using
              a c99 compiler)
              [color=blue]
              > st_Test *pst_Test;[/color]

              should be
              struct st_Test *pst_Test;
              [color=blue]
              > pst_Test = NULL; // pointer not valid yet
              > for(int i = 0;i <=MAX_STRUCT_SI ZE;i++)
              > {
              > if(!pst_Test) // not yet allocated
              > pst_Test = (st_Test*)mallo c(1 *[/color]
              sizeof(st_Test) );

              why the cast ? did the compiler beat you over the head when you
              left it out ? do you think perhaps that the cast is hiding problems ?

              also, why do you have 1 * sizeof (st_Test), when sizeof st_Test
              (or even better, sizeof *pst_Test) would do ?
              [color=blue]
              > else // Resize by 1[/color]

              you forgot to make sure that malloc returned a pointer to valid
              memory. what happens if there is no more memory ?[color=blue]
              > pst_Test = (st_Test*)reall oc(pst_Test,(i+ 1)
              > *sizeof(st_Test )); /// This is the Leak /////////[/color]

              a). maybe some clean indentation would help your (and others)
              comprehension.
              b). you are not making sure that realloc returned memory to you.
              you must *always* check the return values of malloc/realloc/etc.
              c). stop the casting.
              d). those are not comments.
              [color=blue]
              > // Reset the buffer we got
              > memset(&pst_Tes t[i],'\0',sizeof(st _Test));
              > // Add some data to the allocated struct
              > pst_Test[i].iInt = 64738;
              > strcpy(pst_Test[i].szChar,"poke 53280,1");[/color]
              <ot>
              <grin>
              this isn't sposed to run on a c64, right ?
              </ot>[color=blue]
              > // allocate buffer for the void* element ////// This[/color]
              is[color=blue]
              > where bound checker found the problem ///
              > if(!pst_Test[i].pVoid)[/color]

              what is this test supposed to achieve ?
              [color=blue]
              > pst_Test[i].pVoid = (char*)malloc(3 2);[/color]

              lose the casts.
              [color=blue]
              > strcpy((char*)p st_Test[i].pVoid,"commodr e 64");
              > }
              >
              > ////////////////////////////////////////////////// End
              >[/color]
              ///////////////////////////////////////////////////////////////////////

              ok, so where is the code that frees all the memory ? no wonder
              its leaking ...

              how about you work on the code till it compiles as a clean
              C proggy, then repost, and we'll try to spot the leak ?

              goose,
              professional layabout and arcade-game player,
              poke 53281,0 :-)

              [ See http://www.gotw.ca/resources/clcm.htm for info about ]
              [ comp.lang.c++.m oderated. First time posters: Do this! ]

              Comment

              • Vinayak Raghuvamshi

                #8
                Re: Impossible Leak realloc

                Eitan Michaelson <m_eitan@netvis ion.net.il> wrote in message
                news:<bdgrml$dr f$1@news2.netvi sion.net.il>...[color=blue]
                > Hi,
                >
                > Can any one tell me what's wrong with this code?
                >
                > It leaks (acceding to bound checker), when it attempts to reallocate[/color]
                memory.[color=blue]
                >
                > The code is not pure C, but with minor adjustments any C compiler[/color]
                would[color=blue]
                > compile this.
                >
                >
                > #include <stdio.h>
                > #include <malloc.h>
                > #include <string.h>
                >
                > #define MAX_STRUCT_SIZE (50)
                > struct st_Test
                > {
                > char szChar[32];
                > int iInt;
                > void *pVoid;
                > };
                > void main(void)
                > {
                > // Pointer to the structure
                > st_Test *pst_Test;
                > pst_Test = NULL; // pointer not valid yet
                > for(int i = 0;i <=MAX_STRUCT_SI ZE;i++)
                > {
                > if(!pst_Test) // not yet allocated
                > pst_Test = (st_Test*)mallo c(1 *[/color]
                sizeof(st_Test) );[color=blue]
                > else // Resize by 1
                > pst_Test = (st_Test*)reall oc(pst_Test,(i+ 1)
                > *sizeof(st_Test )); /// This is the Leak /////////
                > // Reset the buffer we got
                > memset(&pst_Tes t[i],'\0',sizeof(st _Test));[/color]

                Unless I am missing something, I think the leak is obvious.
                where are you freeing ur mallocated memory ?

                -Vinayak

                [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                [ comp.lang.c++.m oderated. First time posters: Do this! ]

                Comment

                • bd

                  #9
                  Re: Impossible Leak realloc

                  On Fri, 27 Jun 2003 07:01:37 -0400, Eitan Michaelson wrote:
                  [color=blue]
                  > Hi,
                  >
                  > Can any one tell me what's wrong with this code?
                  >
                  > It leaks (acceding to bound checker), when it attempts to reallocate[/color]
                  memory.[color=blue]
                  >
                  > The code is not pure C, but with minor adjustments any C compiler[/color]
                  would[color=blue]
                  > compile this.[/color]

                  The only problem I see is void main - and this should be fixed.
                  [color=blue]
                  >
                  >
                  >
                  > Thank you
                  >
                  > Eitan Michaelson.
                  >
                  >
                  >
                  > ////////////////////////////////////////////////// Code Starts Here
                  >[/color]
                  ///////////////////////////////////////////////////////////////////////[color=blue]
                  >
                  >
                  >
                  > // This code attempts to create a pointer to a structure,and then[/color]
                  allocate a[color=blue]
                  > buffer for that structure, so it would hold an array of structures.
                  >
                  > // in each loop I’m trying to reallocate the structure array so it[/color]
                  would[color=blue]
                  > grow by 1, and then I'm trying to add data into it.
                  >
                  > // one of the structure elements is a void*, which in turn is[/color]
                  allocated by[color=blue]
                  > malloc.
                  >
                  >
                  >
                  >
                  > #include <stdio.h>
                  > #include <malloc.h>
                  > #include <string.h>
                  >
                  > #define MAX_STRUCT_SIZE (50)
                  > struct st_Test
                  > {
                  > char szChar[32];
                  > int iInt;
                  > void *pVoid;
                  > };
                  > void main(void)[/color]

                  int main(void)
                  [color=blue]
                  > {
                  > // Pointer to the structure
                  > st_Test *pst_Test;
                  > pst_Test = NULL; // pointer not valid yet
                  > for(int i = 0;i <=MAX_STRUCT_SI ZE;i++)
                  > {
                  > if(!pst_Test) // not yet allocated
                  > pst_Test = (st_Test*)mallo c(1 *[/color]
                  sizeof(st_Test) );[color=blue]
                  > else // Resize by 1
                  > pst_Test = (st_Test*)reall oc(pst_Test,(i+ 1)
                  > *sizeof(st_Test )); /// This is the Leak /////////[/color]

                  You never free pst_Test.
                  [color=blue]
                  > // Reset the buffer we got
                  > memset(&pst_Tes t[i],'\0',sizeof(st _Test));[/color]

                  This is not a standard way to clear it. How about:
                  pst_Test[i].pVoid = pst_Test.iInt = pst_Test.szChar[0] = 0;
                  It'll probably be faster, too. In fact, since you reset everything in
                  the
                  code below, it's totally unnecessary.
                  [color=blue]
                  > // Add some data to the allocated struct
                  > pst_Test[i].iInt = 64738;
                  > strcpy(pst_Test[i].szChar,"poke 53280,1");
                  > // allocate buffer for the void* element ////// This[/color]
                  is[color=blue]
                  > where bound checker found the problem ///
                  > if(!pst_Test[i].pVoid)
                  > pst_Test[i].pVoid = (char*)malloc(3 2);[/color]

                  You never free that. Therefore, it's a leak. See below for the solution.
                  [color=blue]
                  > strcpy((char*)p st_Test[i].pVoid,"commodr e 64");
                  > }
                  >[/color]
                  for(int i = 0; i <= MAX_STRUCT_SIZE ; i++){
                  free(pst_Test[i].pVoid);
                  }
                  free(pst_test);
                  return 0;
                  }

                  --
                  Freenet distribution not available
                  "A verbal contract isn't worth the paper it's printed on."
                  - Samuel Goldwyn


                  [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                  [ comp.lang.c++.m oderated. First time posters: Do this! ]

                  Comment

                  • Balog Pal

                    #10
                    Re: Impossible Leak realloc

                    [mods: why do you approve completely offtopic messages?]
                    {Sometimes we do by accident, but this thread is not one of those. The
                    OP's code is C++ even if it makes no use of specifically C++ rather than
                    C functionality. -mod}

                    "Eitan Michaelson" <m_eitan@netvis ion.net.il> wrote in message
                    news:bdgrml$drf $1@news2.netvis ion.net.il...

                    Man, this code has nothing to do with C++. And even as C it looks pretty
                    ugly.
                    [color=blue]
                    > It leaks (acceding to bound checker), when it attempts to reallocate[/color]
                    memory.

                    You leak memory when you allocate a block and later you do not free it.
                    [using either free() or realloc(p, 0)]

                    Your code has not a single free operation, so how you expect it could *NOT*
                    leak memory?

                    Paul



                    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                    [ comp.lang.c++.m oderated. First time posters: Do this! ]

                    Comment

                    • Emmanuel Delahaye

                      #11
                      Re: Impossible Leak realloc

                      In 'comp.lang.c', Eitan Michaelson <m_eitan@netvis ion.net.il> wrote:

                      [assuming C]
                      [color=blue]
                      > Can any one tell me what's wrong with this code?
                      >
                      > It leaks (acceding to bound checker), when it attempts to reallocate
                      > memory.
                      >
                      > The code is not pure C, but with minor adjustments any C compiler would
                      > compile this.
                      >
                      >
                      > // This code attempts to create a pointer to a structure,and then
                      > allocate a buffer for that structure, so it would hold an array of
                      > structures.
                      >
                      > // in each loop I'm trying to reallocate the structure array so it
                      > would grow by 1, and then I'm trying to add data into it.
                      >
                      > // one of the structure elements is a void*, which in turn is allocated
                      > by malloc.
                      >
                      >
                      > #include <stdio.h>
                      > #include <malloc.h>[/color]

                      Non standard header. You want <stdlib.h>
                      [color=blue]
                      > #include <string.h>
                      >
                      > #define MAX_STRUCT_SIZE (50)[/color]

                      Sounds more like an ARRAY_SIZE...
                      [color=blue]
                      > struct st_Test
                      > {
                      > char szChar[32];
                      > int iInt;
                      > void *pVoid;
                      > };
                      > void main(void)
                      > {
                      > // Pointer to the structure
                      > st_Test *pst_Test;[/color]

                      st_Test is not defined. If it works with you, you are probably not using a C
                      compiler. You know, C and C++ are very different language, despite the
                      appearences.

                      struct st_Test *pst_Test;
                      [color=blue]
                      > pst_Test = NULL; // pointer not valid yet[/color]

                      In that case, why not doing it in one gulp:

                      struct st_Test *pst_Test = NULL;
                      [color=blue]
                      > for(int i = 0;i <=MAX_STRUCT_SI ZE;i++)[/color]

                      Are you sure you are using a C compiler? You code is full of c++ism. It's
                      boring. (Note you can only use this construct in C with a C99 compiler).
                      [color=blue]
                      > {
                      > if(!pst_Test) // not yet allocated
                      > pst_Test = (st_Test*)mallo c(1 *
                      > sizeof(st_Test) );[/color]

                      Again these casts are c++ism... Get rid of them. NEVER compile C code with a
                      compiler for another language.

                      #ifdef __cplusplus
                      #error Wrong compiler. Use a C one.
                      #endif

                      What is the point of multiplying something by 1 ? Note that realloc() with
                      NULL acts like malloc(). You don't need this 'special case'. realloc()
                      handkes it already.
                      [color=blue]
                      > else // Resize by 1
                      > pst_Test = (st_Test*)reall oc(pst_Test,(i+ 1)
                      > *sizeof(st_Test )); /// This is the Leak /////////[/color]

                      Please avoid to write scary code. Stay simple:

                      pst_Test = realloc(pst_Tes t, (i + 1) * sizeof *pst_Test);

                      but as indicated in the FAQ, realloc() can fail. In that case, you need a
                      temporary pointer.

                      struct st_Test* p = realloc(pst_Tes t, (i + 1) * sizeof *pst_Test);

                      if (p)
                      {
                      pst_Test = p;
                      }
                      else
                      {
                      free (p);
                      }
                      [color=blue]
                      > // Reset the buffer we got
                      > memset(&pst_Tes t[i],'\0',sizeof(st _Test));[/color]

                      memset(pst_Test + i, 0, sizeof *pst_Test);

                      Note that setting all bits to 0 os not the good wauy a setting the elements
                      of a structure to 0. You should use 'zero' reference structure of initialize
                      the elements one by one.
                      [color=blue]
                      > // Add some data to the allocated struct
                      > pst_Test[i].iInt = 64738;[/color]

                      Ok.
                      [color=blue]
                      > strcpy(pst_Test[i].szChar,"poke 53280,1");[/color]

                      Ok, assuming the string is not too large.

                      *pst_Test[i].szChar = 0;
                      strncat(pst_Tes t[i].szChar
                      , "poke 53280,1"
                      , sizeof pst_Test[i].szChar - 1);

                      is safe (and easily 'macroizable' if you find it gory). No need for bound
                      checker now!
                      [color=blue]
                      > // allocate buffer for the void* element ////// This is
                      > where bound checker found the problem ///
                      > if(!pst_Test[i].pVoid)[/color]

                      pVoid was not properly set to NULL.
                      [color=blue]
                      > pst_Test[i].pVoid = (char*)malloc(3 2);
                      > strcpy((char*)p st_Test[i].pVoid,"commodr e 64");[/color]

                      Beware. The strcpy() should also be under the control of the if (). Always
                      use the {} with code structures. It helps readbility and maintenance.
                      [color=blue]
                      > }[/color]

                      missing

                      return 0;
                      }

                      Try that:

                      #include <stdlib.h>

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

                      #define MAX_STRUCT_SIZE (50)
                      struct st_Test
                      {
                      char szChar[32];
                      int iInt;
                      void *pVoid;
                      };

                      int main (void)
                      {
                      /* Pointer to the structure */
                      /* pointer not valid yet */
                      struct st_Test *pst_Test = NULL;
                      int i;

                      for (i = 0; i <= MAX_STRUCT_SIZE ; i++)
                      {
                      /* Resize by 1 */
                      struct st_Test *p = realloc (pst_Test, (i + 1) * sizeof *pst_Test);
                      if (p)
                      {
                      pst_Test = p;

                      /* Reset the buffer we got */
                      {
                      static struct st_Test const z =
                      {
                      {0},
                      0,
                      0,
                      };

                      *p = z;
                      }

                      /* Add some data to the allocated struct */
                      p->iInt = 64738;

                      *p->szChar = 0;
                      strncat (p->szChar, "poke 53280,1", sizeof p->szChar - 1);

                      /* allocate buffer for the void* element */
                      if (!p->pVoid)
                      {
                      p->pVoid = malloc (32);
                      strcpy (p->pVoid, "commodre 64");
                      }
                      }
                      else
                      {
                      /* memory problem */
                      free (pst_Test);
                      break;
                      }
                      }

                      return 0;
                      }

                      --
                      -ed- emdelYOURBRA@no os.fr [remove YOURBRA before answering me]
                      The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
                      C-library: http://www.dinkumware.com/htm_cl/index.html
                      FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

                      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                      [ comp.lang.c++.m oderated. First time posters: Do this! ]

                      Comment

                      • kanze@gabi-soft.fr

                        #12
                        Re: Impossible Leak realloc

                        Eitan Michaelson <m_eitan@netvis ion.net.il> wrote in message
                        news:<bdgrml$dr f$1@news2.netvi sion.net.il>...
                        [color=blue]
                        > Can any one tell me what's wrong with this code?[/color]
                        [color=blue]
                        > It leaks (acceding to bound checker), when it attempts to reallocate memory.[/color]
                        [color=blue]
                        > The code is not pure C, but with minor adjustments any C compiler
                        > would compile this.[/color]

                        It's not legal C++ either, but with a fair number of adjustments...
                        [color=blue]
                        > // This code attempts to create a pointer to a structure,and then
                        > // allocate a buffer for that structure, so it would hold an array of
                        > // structures.[/color]
                        [color=blue]
                        > // in each loop I??m trying to reallocate the structure array so it
                        > // would grow by 1, and then I'm trying to add data into it.[/color]
                        [color=blue]
                        > // one of the structure elements is a void*, which in turn is
                        > // allocated by malloc.[/color]
                        [color=blue]
                        > #include <stdio.h>
                        > #include <malloc.h>[/color]

                        There is no such header in C or in C++.
                        [color=blue]
                        > #include <string.h>[/color]
                        [color=blue]
                        > #define MAX_STRUCT_SIZE (50)
                        > struct st_Test
                        > {
                        > char szChar[32];
                        > int iInt;
                        > void *pVoid;
                        > };[/color]
                        [color=blue]
                        > void main(void)[/color]

                        In C++, at least, main *must* return an int. In C it normally returns
                        an int as well, but I think the C standard allows a conformant compiler
                        to accept a void return as an extension. As an extension -- "void main"
                        is not standard conforming C.
                        [color=blue]
                        > {
                        > // Pointer to the structure
                        > st_Test *pst_Test;[/color]

                        This line shouldn't pass a C complier, although it is legal C++. If you
                        wrote:

                        struct st_Test* pst_Test ;

                        it would be legal in both languages.
                        [color=blue]
                        > pst_Test = NULL; // pointer not valid yet
                        > for(int i = 0;i <=MAX_STRUCT_SI ZE;i++)
                        > {
                        > if(!pst_Test) // not yet allocated
                        > pst_Test = (st_Test*)mallo c(1 * sizeof(st_Test) );
                        > else // Resize by 1
                        > pst_Test = (st_Test*)reall oc(pst_Test,(i+ 1)
                        > *sizeof(st_Test )); /// This is the Leak /////////[/color]

                        You don't need the test -- realloc is guaranteed to work correctly if
                        passed a NULL pointer.
                        [color=blue]
                        > // Reset the buffer we got
                        > memset(&pst_Tes t[i],'\0',sizeof(st _Test));[/color]

                        I'm not sure what you are trying to do here, but you initialize the
                        pVoid element to a possibly invalid value, both in C and in C++.

                        If you want the equivalent of zero initialization, the standard idiom
                        would be to define a static object, and assign from it:

                        static struct st_Test zeroInitialized ;
                        pst_Test[ i ] = zeroInitialized ;
                        [color=blue]
                        > // Add some data to the allocated struct
                        > pst_Test[i].iInt = 64738;
                        > strcpy(pst_Test[i].szChar,"poke 53280,1");
                        > // allocate buffer for the void* element ////// This is
                        > where bound checker found the problem ///
                        > if(!pst_Test[i].pVoid)[/color]

                        This line contains undefined behavior. Both in C and in C++.
                        [color=blue]
                        > pst_Test[i].pVoid = (char*)malloc(3 2);
                        > strcpy((char*)p st_Test[i].pVoid,"commodr e 64");
                        > }[/color]
                        [color=blue]
                        > ////////////////////////////////////////////////// End
                        > ///////////////////////////////////////////////////////////////////////[/color]

                        Of course, since you never free any memory, it is normal that you have a
                        memory leak. The code returns from main, and the only pointer to your
                        structures disappears, so any checker will call it a leak.

                        --
                        James Kanze GABI Software mailto:kanze@ga bi-soft.fr
                        Conseils en informatique oriente objet/ http://www.gabi-soft.fr
                        Beratung in objektorientier ter Datenverarbeitu ng
                        11 rue de Rambouillet, 78460 Chevreuse, France, Tl. : +33 (0)1 30 23 45 16

                        [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                        [ comp.lang.c++.m oderated. First time posters: Do this! ]

                        Comment

                        Working...