Can I Trust Pointer Arithmetic In Re-Allocated Memory?

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

    #16
    Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?

    On Sat, 12 Aug 2006 23:55:11 GMT, "Bill Reid"
    <hormelfree@hap pyhealthy.netwr ote:
    >
    >Barry Schwarz <schwarzb@doezl .netwrote in message
    >news:nm7qd2dur a0jcplvn9s0g5o4 73eb149mo3@4ax. com...
    >On Fri, 11 Aug 2006 06:09:21 GMT, "Bill Reid"
    ><hormelfree@ha ppyhealthy.netw rote:
    >Barry Schwarz <schwarzb@doezl .netwrote in message
    >news:k93od21vg d6n6fhrg6tooem3 r5j06ejrq4@4ax. com...
    >On Fri, 11 Aug 2006 03:54:19 GMT, "Bill Reid"
    ><hormelfree@ha ppyhealthy.netw rote:
    >>
    >You memory is
    >allocated from address to address+size-1. Furthermore, calculating
    >the value address+size is always allowed but you may not dereference
    >this address.
    >>
    >...you wouldn't want to dereference an address, right.
    >>
    >It's a very common thing to do. How else do you get the value at that
    >address? All subscripts involve an implied dereference.
    >>
    >OK, you were talking about dereferencing an address one element
    >past the end of the block, I thought you were talking about something like
    >saving the pointer, then trying to use it again after another realloc().
    >That WOULD be a recipe for diasaster, right?
    The point I was trying to make was: After the successful allocation,
    you could dereference any address in the range address to
    address+size-1. While it is legal to compute the value address+size
    it is not legal to dereference it.

    After calling realloc, any address based on the "before" location is
    probably invalid. The only time it would be valid is if:

    The address returned from realloc was the same as the address
    passed to the function in argument 1 and

    The offset into the area (address of interest - starting address
    of area) <= size argument passed to realloc.
    >
    >So I'm not sure what distinction you're trying to make about
    >subscript "implied" dereferencing. Isn't "address+si ze" equivalent to
    You asked why someone would want to dereference an address. I tried
    to give an example of why it is a very common thing to do.
    >"address[size]"? Again, the only problem in doing anything with a
    In my discussion, I used the phrase address+size in its non-C
    arithmetic meaning. In C, the meaning is equivalent only for pointers
    where the sizeof the object pointed to is 1.

    In C address[size] is defined to be *(address+size) , remembering that
    pointer arithmetic includes implied scaling by the sizeof the object
    pointed to.
    >dereference of that address is that you're one element past the
    >end of the block...but that might actually work for you if you're Russian...
    The "problem" is that dereferencing the address invokes undefined
    behavior, even before you attempt to do something with the object that
    may be retrieved from that address.


    Remove del for email

    Comment

    • Herbert Rosenau

      #17
      Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?

      On Sun, 13 Aug 2006 16:14:19 UTC, "Bill Reid"
      <hormelfree@hap pyhealthy.netwr ote:
      What I forgot was that if I don't malloc() the block first, if I
      realloc() in a loop I get a memory access exception. I hate it
      when that happens...
      void *p = NULL; /* we have no memory yet */
      void *temp; /* realloc will set it */

      size_t size = 0; /* we calculate the size in the loop before we call
      realloc */
      ....
      for (....) {
      ....
      if ((temp = realloc(p, size) != NULL) {
      /* realloc failed */
      return NULL; /* or some other error code */
      }
      p = temp;
      ....
      }
      free(p);

      will work always - except your implementation is really broken. But
      hten trow your compiler into trash and get another one.
      Maybe it IS a bug in the compiler, if it wasn't so easy to work
      around, I might actually worry about it more. As it is, I did a
      search on the compiler maker's web-site for any information
      on known bugs, came up with nothing, and left a question on
      the discussion forum about it, see if anybody knows anything...
      I would say you have forgotten to initialise the pointer given to
      realloc with NULL signalling it that thre is currently nothing to
      realloc but malloc.

      --
      Tschau/Bye
      Herbert

      Visit http://www.ecomstation.de the home of german eComStation
      eComStation 1.2 Deutsch ist da!

      Comment

      • Bill Reid

        #18
        Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?


        Herbert Rosenau <os2guy@pc-rosenau.dewrote in message
        news:wmzsGguTDN 6N-pn2-KdbpSkdEwzDo@JU PITER1.PC-ROSENAU.DE...
        On Sun, 13 Aug 2006 16:14:19 UTC, "Bill Reid"
        <hormelfree@hap pyhealthy.netwr ote:
        >
        What I forgot was that if I don't malloc() the block first, if I
        realloc() in a loop I get a memory access exception. I hate it
        when that happens...
        >
        void *p = NULL; /* we have no memory yet */
        void *temp; /* realloc will set it */
        >
        size_t size = 0; /* we calculate the size in the loop before we call
        realloc */
        ...
        for (....) {
        ....
        if ((temp = realloc(p, size) != NULL) {
        /* realloc failed */
        return NULL; /* or some other error code */
        }
        p = temp;
        ....
        }
        free(p);
        >
        will work always - except your implementation is really broken. But
        hten trow your compiler into trash and get another one.
        >
        Maybe it IS a bug in the compiler, if it wasn't so easy to work
        around, I might actually worry about it more. As it is, I did a
        search on the compiler maker's web-site for any information
        on known bugs, came up with nothing, and left a question on
        the discussion forum about it, see if anybody knows anything...
        >
        I would say you have forgotten to initialise the pointer given to
        realloc with NULL signalling it that thre is currently nothing to
        realloc but malloc.
        >
        You are correct sir!

        I made yet a further fool of myself and posted the question on
        the message board for the compiler. Sure enough, I "forgot" that
        local pointers are not initialized, therefore are not NULL and
        could be anything, so realloc() tries to allocate memory in
        god-knows-where.

        Of course, I could have sworn that I explicitly set the pointer
        to NULL as the FIRST thing I tried to fix the problem when
        it first cropped up years ago, but I must have mucked that up
        somehow.

        As to your code, I'm not sure why you do the two-step
        with "*p" and "*temp"...i t seems like all is required is to set
        *p=NULL when declared, at least that's what I did, and
        it worked just fine. Am I (again!) missing something?

        ---
        William Ernest Reid



        Comment

        • Bill Reid

          #19
          Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?


          Barry Schwarz <schwarzb@doezl .netwrote in message
          news:3loud2ts36 55cklsac99kvk7j el47gnur7@4ax.c om...
          On Sat, 12 Aug 2006 23:55:11 GMT, "Bill Reid"
          <hormelfree@hap pyhealthy.netwr ote:
          >
          dereference of that address is that you're one element past the
          end of the block...but that might actually work for you if you're
          Russian...
          >
          The "problem" is that dereferencing the address invokes undefined
          behavior, even before you attempt to do something with the object that
          may be retrieved from that address.
          >
          Oh really. Well, throw that onto the giant pile of stuff I did not
          know about C programming...

          In any event, I did solve a bunch of "problems" in my code as a result
          of asking these stupid questions. My code basically runs exactly as it
          did before, would compile just as cleanly on any compiler as before, but
          it now no longer has certain "problems"!

          Thanks guys!

          ---
          William Ernest Reid



          Comment

          • Herbert Rosenau

            #20
            Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?

            On Wed, 16 Aug 2006 01:01:06 UTC, "Bill Reid"
            <hormelfree@hap pyhealthy.netwr ote:

            Anybody blames her/himself as s/he can. :-) You will learn that
            mostenly when you tries to blame the compiler you blames yourself
            instead.
            >
            As to your code, I'm not sure why you do the two-step
            with "*p" and "*temp"...i t seems like all is required is to set
            *p=NULL when declared, at least that's what I did, and
            it worked just fine. Am I (again!) missing something?
            p is the pointer holding the address of the memory block. As realloc
            an fail (returning NULL) you needs another pointer to assign the
            result of realloc until you knows that realloc returns (new) memory
            address.

            When realloc fails you needs to either work with the memory (p) you
            have already or to cleanup (free(p). Overwriting p with NULL gives you
            a memory leak as you lost the address of the memory you have laready
            allocated.

            Another tip:

            You should initialise any variable when defining it to be sure to fail
            on that because you've not already assigned a known valid value. So
            initialise a 0 (or a value you can easyly identify as invalid to data
            and NULL to pointer. Then learn how to use a debugger and set a
            breakpoint immediately before the fail occures, analyse the date found
            there and then, when anything seems ok step a single step forward and
            analyse again until the failture occures.

            --
            Tschau/Bye
            Herbert

            Visit http://www.ecomstation.de the home of german eComStation
            eComStation 1.2 Deutsch ist da!

            Comment

            • Bill Reid

              #21
              Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?


              Herbert Rosenau <os2guy@pc-rosenau.dewrote in message
              news:wmzsGguTDN 6N-pn2-Chy9PK7Cy7sV@JU PITER1.PC-ROSENAU.DE...
              On Wed, 16 Aug 2006 01:01:06 UTC, "Bill Reid"
              <hormelfree@hap pyhealthy.netwr ote:
              >
              Anybody blames her/himself as s/he can. :-) You will learn that
              mostenly when you tries to blame the compiler you blames yourself
              instead.
              >
              I blame society.

              As to your code, I'm not sure why you do the two-step
              with "*p" and "*temp"...i t seems like all is required is to set
              *p=NULL when declared, at least that's what I did, and
              it worked just fine. Am I (again!) missing something?
              >
              p is the pointer holding the address of the memory block. As realloc
              an fail (returning NULL) you needs another pointer to assign the
              result of realloc until you knows that realloc returns (new) memory
              address.
              >
              When realloc fails you needs to either work with the memory (p) you
              have already or to cleanup (free(p). Overwriting p with NULL gives you
              a memory leak as you lost the address of the memory you have laready
              allocated.
              >
              Hmmm...if this is the case this should be in the NON-documentation.
              Actually, I guess it kind of is, but after a quick read of this I always
              thought realloc() freed the original memory block and returned NULL
              if it couldn't reallocate the new block:

              ....

              Syntax

              #include <stdlib.h>
              void *realloc(void *block, size_t size);

              ....

              If the block cannot be reallocated, realloc returns NULL.

              If the value of size is 0, the memory block is freed and realloc returns
              NULL.

              ---end of NON-documentation

              I guess I got the last two conditions conflated in my mind; it just seemed
              logical to me that if realloc() failed it would free the previous block.
              It SEEMS like it should.

              As an orthogonal point, what horrible things happen if you try
              to free() a NULL pointer?
              Another tip:
              >
              You should initialise any variable when defining it to be sure to fail
              on that because you've not already assigned a known valid value. So
              initialise a 0 (or a value you can easyly identify as invalid to data
              and NULL to pointer. Then learn how to use a debugger and set a
              breakpoint immediately before the fail occures, analyse the date found
              there and then, when anything seems ok step a single step forward and
              analyse again until the failture occures.
              >
              I'm not quite sure how this is functionally different from SOP using
              a debugger; initialized or not, I can "mouse over" ALL the variables
              after an exeption point or break point, so I don't see garbage at an
              exception point I step back and put in a break, run it again, check
              the values, step forward, etc.

              ---
              William Ernest Reid



              Comment

              • Keith Thompson

                #22
                Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?

                "Bill Reid" <hormelfree@hap pyhealthy.netwr ites:
                [...]
                As an orthogonal point, what horrible things happen if you try
                to free() a NULL pointer?
                Nothing; free(NULL) is guaranteed to be a no-op.

                Either your system's documentation or any decent C textbook should
                tell you this. Failing that, you can download a copy of the latest
                draft of the C standard; search for "n1124.pdf" .

                --
                Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
                We must do something. This is something. Therefore, we must do this.

                Comment

                • Herbert Rosenau

                  #23
                  Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?

                  On Thu, 17 Aug 2006 23:54:41 UTC, "Bill Reid"
                  <hormelfree@hap pyhealthy.netwr ote:
                  When realloc fails you needs to either work with the memory (p)
                  you
                  have already or to cleanup (free(p). Overwriting p with NULL gives you
                  a memory leak as you lost the address of the memory you have laready
                  allocated.
                  Hmmm...if this is the case this should be in the NON-documentation.
                  Actually, I guess it kind of is, but after a quick read of this I always
                  thought realloc() freed the original memory block and returned NULL
                  if it couldn't reallocate the new block:
                  Yes, but it does NOT free() the old block then. That block leaves
                  unchanged.
                  ...
                  >
                  Syntax
                  >
                  #include <stdlib.h>
                  void *realloc(void *block, size_t size);
                  >
                  ...
                  >
                  If the block cannot be reallocated, realloc returns NULL.
                  >
                  If the value of size is 0, the memory block is freed and realloc returns
                  NULL.
                  >
                  ---end of NON-documentation
                  >
                  I guess I got the last two conditions conflated in my mind; it just seemed
                  logical to me that if realloc() failed it would free the previous block.
                  It SEEMS like it should.
                  But it does not so because you may need to continue your work with the
                  old block.
                  When you have no need for the old block you have to free() that
                  yourself, else you should free() it. In any case you needs its
                  address.
                  As an orthogonal point, what horrible things happen if you try
                  to free() a NULL pointer?
                  Nothing. free(NULL); works like a noop. Nothing occures. That is
                  guaranteed.

                  --
                  Tschau/Bye
                  Herbert

                  Visit http://www.ecomstation.de the home of german eComStation
                  eComStation 1.2 Deutsch ist da!

                  Comment

                  • Bill Reid

                    #24
                    Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?


                    Herbert Rosenau <os2guy@pc-rosenau.dewrote in message
                    news:wmzsGguTDN 6N-pn2-ysKU5ddsUS8X@JU PITER1.PC-ROSENAU.DE...
                    On Thu, 17 Aug 2006 23:54:41 UTC, "Bill Reid"
                    <hormelfree@hap pyhealthy.netwr ote:

                    I guess I got the last two conditions conflated in my mind; it just
                    seemed
                    logical to me that if realloc() failed it would free the previous block.
                    It SEEMS like it should.
                    >
                    But it does not so because you may need to continue your work with the
                    old block.
                    Sure, but right off-hand I can't think of single case where I would
                    actually want to do anything with "half a loaf". When memory
                    allocation fails in whole or in part, I just want to get out of there
                    as quickly as possible, maybe just break out of that particular
                    module operation, quite often just to exit the whole program.

                    I suspect that is true of the vast majority of programs out there.
                    So not automatically freeing the block seems to be a case of "the
                    needs of the few outweighing the needs of the many".
                    When you have no need for the old block you have to free() that
                    yourself, else you should free() it. In any case you needs its
                    address.
                    >
                    In this imperfect world, I guess so...what a friggin' hassle...
                    As an orthogonal point, what horrible things happen if you try
                    to free() a NULL pointer?
                    >
                    Nothing. free(NULL); works like a noop. Nothing occures. That is
                    guaranteed.
                    >
                    So I've kind of been wasting a little time with these types of
                    generalized pre-exit memory cleanup routines:

                    void free_time_serie s_mem(void) {
                    unsigned ts_idx;

                    for(ts_idx=0;ts _idx<TS_MAX;ts_ idx++) {
                    if(time_series[ts_idx]!=NULL) {
                    free(time_serie s[ts_idx]);
                    time_series[ts_idx]=NULL;
                    }
                    }

                    num_series=0;
                    }

                    Not only don't I need:
                    if(time_series[ts_idx]!=NULL)

                    What the hell is the point of:
                    time_series[ts_idx]=NULL;

                    ??? Who knows...what the hell was I thinking...oh, wait, I WASN'T
                    thinking...

                    However, note the clever use of the "TS_MAX" define; NO "MAGIC
                    NUMBER" HERE FOR THIS BOY!!!

                    ---
                    William Ernest Reid



                    Comment

                    • Ben Pfaff

                      #25
                      Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?

                      "Bill Reid" <hormelfree@hap pyhealthy.netwr ites:
                      Herbert Rosenau <os2guy@pc-rosenau.dewrote in message
                      news:wmzsGguTDN 6N-pn2-ysKU5ddsUS8X@JU PITER1.PC-ROSENAU.DE...
                      >On Thu, 17 Aug 2006 23:54:41 UTC, "Bill Reid"
                      ><hormelfree@ha ppyhealthy.netw rote:
                      >
                      I guess I got the last two conditions conflated in my mind; it just
                      seemed
                      logical to me that if realloc() failed it would free the previous block.
                      It SEEMS like it should.
                      >>
                      >But it does not so because you may need to continue your work with the
                      >old block.
                      >
                      Sure, but right off-hand I can't think of single case where I would
                      actually want to do anything with "half a loaf". When memory
                      allocation fails in whole or in part, I just want to get out of there
                      as quickly as possible, maybe just break out of that particular
                      module operation, quite often just to exit the whole program.
                      >
                      I suspect that is true of the vast majority of programs out there.
                      So not automatically freeing the block seems to be a case of "the
                      needs of the few outweighing the needs of the many".
                      You can write a wrapper function for the standard realloc that
                      does what you want. It's not possible to wrap a function that
                      has your desired behavior to do what the standard realloc does.
                      --
                      "Your correction is 100% correct and 0% helpful. Well done!"
                      --Richard Heathfield

                      Comment

                      • Herbert Rosenau

                        #26
                        Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?

                        On Fri, 18 Aug 2006 23:27:03 UTC, "Bill Reid"
                        <hormelfree@hap pyhealthy.netwr ote:
                        >
                        Herbert Rosenau <os2guy@pc-rosenau.dewrote in message
                        news:wmzsGguTDN 6N-pn2-ysKU5ddsUS8X@JU PITER1.PC-ROSENAU.DE...
                        On Thu, 17 Aug 2006 23:54:41 UTC, "Bill Reid"
                        <hormelfree@hap pyhealthy.netwr ote:
                        >
                        I guess I got the last two conditions conflated in my mind; it just
                        seemed
                        logical to me that if realloc() failed it would free the previous block.
                        It SEEMS like it should.
                        But it does not so because you may need to continue your work with the
                        old block.
                        >
                        Sure, but right off-hand I can't think of single case where I would
                        actually want to do anything with "half a loaf". When memory
                        allocation fails in whole or in part, I just want to get out of there
                        as quickly as possible, maybe just break out of that particular
                        module operation, quite often just to exit the whole program.
                        .... and leaving the database in an undefined state. Maybe you needs a
                        lot of single steps on the incloplete data to do to unwind any action
                        you've already done with. So the data is needed by your program. Most
                        programs are more complex in data handling as you currently aware of.

                        So the best realloc can do for you to flag the error that it is out of
                        memory and leave data it arrived unchanged. Sometimes you gets a
                        chance to continue when you free()s some other data area.
                        Sometimes you'll split the aready occupied block into one or more
                        smaller ones, write older, smaller blocks out and reuse them.

                        There are lots of possibilities to continue even without - or with -
                        asking the user. Exit is seldom the choice in real programs. Often you
                        will have a solution for "out of memory" on a higher level.

                        exit() is good for ingenious programs but the real world is more
                        complex. So realloc gives you the chance for a real cleanup of any
                        kind you may need. It is simply a bug to overwrite a data area you
                        have already allocated with a null pointer. You have to cleanup.
                        I suspect that is true of the vast majority of programs out there.
                        So not automatically freeing the block seems to be a case of "the
                        needs of the few outweighing the needs of the many".
                        You not written a reals program using realloc. You will then quickly
                        revise your standpoint.
                        When you have no need for the old block you have to free() that
                        yourself, else you should free() it. In any case you needs its
                        address.
                        In this imperfect world, I guess so...what a friggin' hassle...
                        >
                        As an orthogonal point, what horrible things happen if you try
                        to free() a NULL pointer?
                        Nothing. free(NULL); works like a noop. Nothing occures. That is
                        guaranteed.
                        So I've kind of been wasting a little time with these types of
                        generalized pre-exit memory cleanup routines:
                        >
                        void free_time_serie s_mem(void) {
                        unsigned ts_idx;
                        >
                        for(ts_idx=0;ts _idx<TS_MAX;ts_ idx++) {
                        if(time_series[ts_idx]!=NULL) {
                        free(time_serie s[ts_idx]);
                        time_series[ts_idx]=NULL;
                        }
                        }
                        >
                        num_series=0;
                        }
                        >
                        Not only don't I need:
                        if(time_series[ts_idx]!=NULL)
                        >
                        What the hell is the point of:
                        time_series[ts_idx]=NULL;
                        That is needed to save yourself from accessing data you've given back
                        to the system. The only point where you would savely NOT set the
                        free()'d pointer to NULL is when the pointer and the data it points to
                        is only alive only inside the function you calls free() AND one of the
                        next statements is return, In any other case setting it to NULL will
                        give you a clean "access of pointer to 0 instead of undefined
                        behavior.


                        --
                        Tschau/Bye
                        Herbert

                        Visit http://www.ecomstation.de the home of german eComStation
                        eComStation 1.2 Deutsch ist da!

                        Comment

                        • Bill Reid

                          #27
                          Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?


                          Herbert Rosenau <os2guy@pc-rosenau.dewrote in message
                          news:wmzsGguTDN 6N-pn2-ixTCUZdIJlc7@JU PITER1.PC-ROSENAU.DE...
                          On Fri, 18 Aug 2006 23:27:03 UTC, "Bill Reid"
                          <hormelfree@hap pyhealthy.netwr ote:
                          Herbert Rosenau <os2guy@pc-rosenau.dewrote in message
                          news:wmzsGguTDN 6N-pn2-ysKU5ddsUS8X@JU PITER1.PC-ROSENAU.DE...
                          On Thu, 17 Aug 2006 23:54:41 UTC, "Bill Reid"
                          <hormelfree@hap pyhealthy.netwr ote:

                          I guess I got the last two conditions conflated in my mind; it just
                          seemed
                          logical to me that if realloc() failed it would free the previous
                          block.
                          It SEEMS like it should.
                          >
                          But it does not so because you may need to continue your work with the
                          old block.
                          Sure, but right off-hand I can't think of single case where I would
                          actually want to do anything with "half a loaf". When memory
                          allocation fails in whole or in part, I just want to get out of there
                          as quickly as possible, maybe just break out of that particular
                          module operation, quite often just to exit the whole program.
                          >
                          ... and leaving the database in an undefined state.
                          Maybe YOUR database. I started this whole thread while looking
                          at a specific operation in one specific module. Each operation in the
                          module downloads several raw data files from the net, parses out the
                          data items, and writes the data to a database. Unless I get ALL of
                          the data, ALL of the files downloaded properly in the correct format
                          and with the correct data, NOTHING, none of the about 100,000
                          data items in this specific operation gets written to the database.

                          I specifically DESIGNED these download modules to work
                          this way, even though the database can never be "undefined" (if data
                          is written to the database, attempts to "over-write" it can't occur and
                          don't matter anyway), out of force of habit writing the routines that
                          analyze the data. In those modules, it is a complete waste of time to
                          in any way analyze partial data, so if I can't download it all from the
                          database, I just give up (except that's actually never happened,
                          probably because I run that stuff at night with no other processes
                          running).
                          Maybe you needs a
                          lot of single steps on the incloplete data to do to unwind any action
                          you've already done with.
                          Well, maybe YOU do. It's not like I'm not aware of how I could
                          corrupt my results or my database, it's just that I design the various
                          parts of the program to avoid these types of situations.
                          So the data is needed by your program. Most
                          programs are more complex in data handling as you currently aware of.
                          >
                          Possibly...and maybe not. I've seen some REALLY "complex"
                          programs in my time, and on a LOC basis alone (or any other basis)
                          I can't really classify what I do as "simple"... but I'm definitely not
                          multi-threading or some other things that might dramatically increase
                          the "complexity "...
                          So the best realloc can do for you to flag the error that it is out of
                          memory and leave data it arrived unchanged. Sometimes you gets a
                          chance to continue when you free()s some other data area.
                          Sometimes you'll split the aready occupied block into one or more
                          smaller ones, write older, smaller blocks out and reuse them.
                          >
                          Hmmmm, yeah, I was afraid of this type of response...yeah , there's
                          about a million things I COULD do, I just DON'T...

                          You may have missed the part where I said I only care that my
                          stuff WORKS, works flawlessly, and blindingly-fast for the amount
                          of data being processed. I'm not TRYING to generate bugs,
                          cuz I don't get paid to fix them, I just LOSE money...
                          There are lots of possibilities to continue even without - or with -
                          asking the user.
                          I thought the general drill was to ask the user (in this case, I'm the
                          only user) to close out some other applications. But I guess another
                          general strategy for the "commercial market" is to let the thing sit
                          there and grind away pointlessly; at least it keeps the room warm
                          on a cold day...
                          Exit is seldom the choice in real programs.
                          Yeah, I think I'm getting your point here, it's just that it doesn't
                          really have anything to do with "complexity ", but something else...
                          Often you
                          will have a solution for "out of memory" on a higher level.
                          >
                          Yeah, but I would suspect these would all slow you down to
                          a crawl...for my purposes, I'll pass, but again, for the "commercial "
                          market it might make sense...and since most software is written for
                          the "commercial " market, maybe it DOES make "statistica l" sense
                          for realloc() to work that way...
                          exit() is good for ingenious programs but the real world is more
                          complex.
                          Well, I don't generally break all the way out to exit(), except in the case
                          of the database initialization stuff whenever I start up, but I probably
                          could
                          since each function tends to clean up after itself on error and return
                          success or failure in some way...
                          So realloc gives you the chance for a real cleanup of any
                          kind you may need. It is simply a bug to overwrite a data area you
                          have already allocated with a null pointer. You have to cleanup.
                          >
                          SOME people have to clean up in that fashion. I'm already clean,
                          I just have to close some open files, release some related memory,
                          I'm good...
                          I suspect that is true of the vast majority of programs out there.
                          So not automatically freeing the block seems to be a case of "the
                          needs of the few outweighing the needs of the many".
                          >
                          You not written a reals program using realloc. You will then quickly
                          revise your standpoint.
                          >
                          If I'm lucky I never WILL write a "real" program. I would hate
                          to be "corrupted" ...
                          When you have no need for the old block you have to free() that
                          yourself, else you should free() it. In any case you needs its
                          address.
                          >
                          In this imperfect world, I guess so...what a friggin' hassle...
                          As an orthogonal point, what horrible things happen if you try
                          to free() a NULL pointer?
                          >
                          Nothing. free(NULL); works like a noop. Nothing occures. That is
                          guaranteed.
                          >
                          So I've kind of been wasting a little time with these types of
                          generalized pre-exit memory cleanup routines:

                          void free_time_serie s_mem(void) {
                          unsigned ts_idx;

                          for(ts_idx=0;ts _idx<TS_MAX;ts_ idx++) {
                          if(time_series[ts_idx]!=NULL) {
                          free(time_serie s[ts_idx]);
                          time_series[ts_idx]=NULL;
                          }
                          }

                          num_series=0;
                          }

                          Not only don't I need:
                          if(time_series[ts_idx]!=NULL)

                          What the hell is the point of:
                          time_series[ts_idx]=NULL;
                          >
                          That is needed to save yourself from accessing data you've given back
                          to the system.
                          Again, you are correct sir! Well, sort of...

                          I mean, that's a good reason TO do it; it's just that I incorrectly
                          described that particular function as a "pre-exit" memory clean-up
                          routine when I quickly looked at it. If was truly "pre-exit", then
                          there would be no need worry about an actual address in
                          the pointer, the next call is to exit() (or return to main(), exit())...
                          The only point where you would savely NOT set the
                          free()'d pointer to NULL is when the pointer and the data it points to
                          is only alive only inside the function you calls free() AND one of the
                          next statements is return, In any other case setting it to NULL will
                          give you a clean "access of pointer to 0 instead of undefined
                          behavior.
                          >
                          ....but I realized after I posted that I also call it when "the user"
                          leaves one particular module for another. Then I could POSSIBLY
                          come back later and have the old pointer laying around to screw
                          me up; it would specifically mess up the purpose of the function
                          I use to populate the array on an "as-needed" basis as any module
                          requires those particular structures:

                          TIME_SERIES *create_time_se ries(void) {
                          unsigned ts_idx;

                          for(ts_idx=0;ts _idx<TS_MAX;ts_ idx++) {
                          if(time_series[ts_idx]==NULL) {
                          if((time_series[ts_idx]=
                          (TIME_SERIES *)malloc(sizeof (TIME_SERIES))) ==NULL) {
                          #ifdef __CONSOLE__
                          printf("\nNot enough memory to create time series");
                          #endif
                          #ifdef __WINGUI__
                          if(MessageDlg(" Not enough memory to create time series",
                          mtConfirmation, TMsgDlgButtons( )<<mbOK,0)==mrO k) ;
                          #endif
                          break;
                          }

                          time_series[ts_idx]->ts_vars=init_t sv;
                          time_series[ts_idx]->ds_vars=init_d sv;
                          num_series++;
                          break;
                          }
                          }

                          return time_series[ts_idx];
                          }

                          Of course, that's all screwed up in the first place because of the
                          ridiculous cast of malloc()...

                          ---
                          William Ernest Reid



                          Comment

                          Working...