malloc error checking

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

    malloc error checking

    At one point in my program I have about a dozen calls to malloc. I want
    to check for malloc failure, but I don't want to write:

    if((buffer_x = malloc(BUFSIZE * sizeof(*buffer_ x))) == NULL)
    {
    exit(EXIT_FAILU RE);
    fprintf(stderr, "malloc failed");
    }

    for each individual call if there is a stylistically better way. How
    would this be handled in commercial code?
  • David REsnick

    #2
    Re: malloc error checking

    Marlene Stebbins wrote:
    [color=blue]
    > At one point in my program I have about a dozen calls to malloc. I want
    > to check for malloc failure, but I don't want to write:
    >
    > if((buffer_x = malloc(BUFSIZE * sizeof(*buffer_ x))) == NULL)
    > {
    > exit(EXIT_FAILU RE);
    > fprintf(stderr, "malloc failed");
    > }
    >
    > for each individual call if there is a stylistically better way. How
    > would this be handled in commercial code?[/color]

    Standard way is to write a wrapper you call in place of malloc
    when you want this behavior. e.g.

    void *safe_malloc(si ze_t size)
    {
    void *ret = malloc(size);
    if (ret == NULL) {
    fprintf(stderr, "malloc %u bytes failed", (unsigned)size) ;
    exit(EXIT_FAILU RE);
    }

    return ret;
    }

    That also has the advantage of letting you decide what to do on
    malloc(0)... No guarantee the printf will work with no memory
    available either, mind you. I added the size to your printf
    and put it before the exit :) The size is useful in case a programming
    error causes you to try to malloc(-1) or some such.

    -David

    Comment

    • Kornilios Kourtis

      #3
      Re: malloc error checking

      Marlene Stebbins <marlene@mail.c om> wrote:[color=blue]
      > At one point in my program I have about a dozen calls to malloc. I want
      > to check for malloc failure, but I don't want to write:
      >
      > if((buffer_x = malloc(BUFSIZE * sizeof(*buffer_ x))) == NULL)
      > {
      > exit(EXIT_FAILU RE);
      > fprintf(stderr, "malloc failed");[/color]
      ^^^^^^^^^^^^^
      this message will never be printed
      because it's after the exit() call
      [color=blue]
      > }
      >[/color]
      [color=blue]
      > for each individual call if there is a stylistically better way. How
      > would this be handled in commercial code?[/color]

      You can use another wrapper function:

      void *malloc_wrap(si ze_t size)
      {
      void *ret;

      ret = malloc(size);
      if (ret == NULL){
      fprintf(stderr, "malloc failed\n");
      exit(EXIT_FAULU RE);
      }

      return ret;
      }

      --
      Kornilios Kourtis

      Computers are useless. They can only give you answers.
      - Pablo Picasso

      Comment

      • Michael Mair

        #4
        Re: malloc error checking


        David REsnick wrote:[color=blue]
        > Marlene Stebbins wrote:
        >[color=green]
        >> At one point in my program I have about a dozen calls to malloc. I
        >> want to check for malloc failure, but I don't want to write:
        >>
        >> if((buffer_x = malloc(BUFSIZE * sizeof(*buffer_ x))) == NULL)
        >> {
        >> exit(EXIT_FAILU RE);
        >> fprintf(stderr, "malloc failed");
        >> }
        >>
        >> for each individual call if there is a stylistically better way. How
        >> would this be handled in commercial code?[/color]
        >
        >
        > Standard way is to write a wrapper you call in place of malloc
        > when you want this behavior. e.g.
        >
        > void *safe_malloc(si ze_t size)
        > {
        > void *ret = malloc(size);
        > if (ret == NULL) {
        > fprintf(stderr, "malloc %u bytes failed", (unsigned)size) ;
        > exit(EXIT_FAILU RE);
        > }
        >
        > return ret;
        > }
        >
        > That also has the advantage of letting you decide what to do on
        > malloc(0)... No guarantee the printf will work with no memory
        > available either, mind you. I added the size to your printf
        > and put it before the exit :) The size is useful in case a programming
        > error causes you to try to malloc(-1) or some such.[/color]

        Note: Under C89, casting to unsigned long (and using %lu) is safer, as
        we do not know how wide size_t actually is. We still might have the
        situation that (size_t)((unsig ned long)((size_t) -1)) != (size_t) -1.
        Under C99 or with a C99 compliant standard library, use the length
        modifier for size_t (z, i.e. %zu).


        Cheers
        Michael
        --
        E-Mail: Mine is a gmx dot de address.

        Comment

        • Rouben Rostamian

          #5
          Re: malloc error checking

          In article <GWUAd.617669$n l.442454@pd7tw3 no>,
          Marlene Stebbins <marlene@mail.c om> wrote:[color=blue]
          >At one point in my program I have about a dozen calls to malloc. I want
          >to check for malloc failure, but I don't want to write:
          >
          > if((buffer_x = malloc(BUFSIZE * sizeof(*buffer_ x))) == NULL)
          > {
          > exit(EXIT_FAILU RE);
          > fprintf(stderr, "malloc failed");
          > }
          >
          >for each individual call if there is a stylistically better way. How
          >would this be handled in commercial code?[/color]

          If all these calls occur within the body of a single function, then
          you may do:


          x1 = malloc(whatever );
          x2 = malloc(whatever );
          ...
          xn = malloc(whatever );

          if (!x1 || !x2 || ... || !xn) {
          fprintf(stderr, "malloc failed");
          exit(EXIT_FAILU RE);
          }

          --
          Rouben Rostamian

          Comment

          • Marlene Stebbins

            #6
            Re: malloc error checking

            Marlene Stebbins wrote:[color=blue]
            > At one point in my program I have about a dozen calls to malloc. I want
            > to check for malloc failure, but I don't want to write:
            >
            > if((buffer_x = malloc(BUFSIZE * sizeof(*buffer_ x))) == NULL)
            > {
            > exit(EXIT_FAILU RE);
            > fprintf(stderr, "malloc failed");
            > }[/color]

            I just noticed that I've got the exit and fprintf statements bass
            ackwards. I should have had another cup of coffee before posting this.

            MS

            Comment

            • Emmanuel Delahaye

              #7
              Re: malloc error checking

              David REsnick wrote on 30/12/04 :[color=blue]
              > void *safe_malloc(si ze_t size)
              > {
              > void *ret = malloc(size);
              > if (ret == NULL) {
              > fprintf(stderr, "malloc %u bytes failed", (unsigned)size) ;
              > exit(EXIT_FAILU RE);
              > }
              >
              > return ret;
              > }[/color]

              I would amend this code this way:

              /* interface (.h) */

              #define safe_malloc(siz e) \
              safe_malloc_ (size, __FILE__, __LINE__)

              void *safe_malloc_ (size_t size, char const *file, int line);


              /* implementation (.c) */

              void *safe_malloc_ (size_t size, char const *file, int line)
              {
              void *p = malloc(size);

              if (p == NULL)
              {
              fprintf (stderr
              , "malloc %lu bytes failed at %s:%d\n"
              , (unsigned long)size
              , file
              , line
              );
              exit (EXIT_FAILURE);
              }
              return ret;
              }

              --
              Emmanuel
              The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
              The C-library: http://www.dinkumware.com/refxc.html

              "C is a sharp tool"

              Comment

              • Eric Sosman

                #8
                Re: malloc error checking

                Marlene Stebbins wrote:
                [color=blue]
                > At one point in my program I have about a dozen calls to malloc. I want
                > to check for malloc failure, but I don't want to write:
                >
                > if((buffer_x = malloc(BUFSIZE * sizeof(*buffer_ x))) == NULL)
                > {
                > exit(EXIT_FAILU RE);
                > fprintf(stderr, "malloc failed");
                > }
                >
                > for each individual call if there is a stylistically better way. How
                > would this be handled in commercial code?[/color]

                "It depends." Here are a few patterns:

                if ((buff1 = malloc(size1)) == NULL
                || (buff2 = malloc(size2)) == NULL
                ...
                || (buff12 = malloc(size12)) == NULL) {
                die_horribly();
                }


                for (i = 0; i < 12; ++i) {
                if ((buff[i] = malloc(size[i])) == NULL)
                die_horribly();
                }


                /* malloc_wrapper( ) dies horribly on failure */
                buff1 = malloc_wrapper( size1);
                buff2 = malloc_wrapper( size2);
                ...
                buff12 = malloc_wrapper( size12);


                char *allbuffs = malloc(size1 + size2 + ... + size12);
                if (allbuffs == NULL)
                die_horribly();
                buff1 = (Type1*)allbuff s;
                buff2 = (Type2*)(allbuf fs + size1);
                ...
                buff12 = (Type12*)(allbu ffs + size1 + size2 + ... + size11);

                .... and many, many more.

                There are at least two lessons in all this. First, there
                are manymanymany ways to organize the handling of failures and
                exceptional conditions in a program. Second, the choice of
                method is usually not driven by the nature of the failure, but
                by the structure of the program.

                --
                Eric Sosman
                esosman@acm-dot-org.invalid

                Comment

                • Jonathan Burd

                  #9
                  Re: malloc error checking

                  Emmanuel Delahaye wrote:[color=blue]
                  > David REsnick wrote on 30/12/04 :
                  >[color=green]
                  >> void *safe_malloc(si ze_t size)
                  >> {
                  >> void *ret = malloc(size);
                  >> if (ret == NULL) {
                  >> fprintf(stderr, "malloc %u bytes failed", (unsigned)size) ;
                  >> exit(EXIT_FAILU RE);
                  >> }
                  >>
                  >> return ret;
                  >> }[/color]
                  >
                  >
                  > I would amend this code this way:
                  >
                  > /* interface (.h) */
                  >
                  > #define safe_malloc(siz e) \
                  > safe_malloc_ (size, __FILE__, __LINE__)
                  >
                  > void *safe_malloc_ (size_t size, char const *file, int line);
                  >
                  >
                  > /* implementation (.c) */
                  >
                  > void *safe_malloc_ (size_t size, char const *file, int line)
                  > {
                  > void *p = malloc(size);
                  >
                  > if (p == NULL)
                  > {
                  > fprintf (stderr
                  > , "malloc %lu bytes failed at %s:%d\n"
                  > , (unsigned long)size
                  > , file
                  > , line
                  > );
                  > exit (EXIT_FAILURE);
                  > }[/color]

                  ret isn't defined. He means return p, anyway.[color=blue]
                  > return ret;
                  > }
                  >[/color]

                  Comment

                  • Emmanuel Delahaye

                    #10
                    Re: malloc error checking

                    (supersedes <mn.f4417d4c83f e5bea.15512@YOU RBRAnoos.fr>)

                    David REsnick wrote on 30/12/04 :[color=blue]
                    > void *safe_malloc(si ze_t size)
                    > {
                    > void *ret = malloc(size);
                    > if (ret == NULL) {
                    > fprintf(stderr, "malloc %u bytes failed", (unsigned)size) ;
                    > exit(EXIT_FAILU RE);
                    > }
                    >
                    > return ret;
                    > }[/color]

                    I would amend this code this way:

                    /* interface (.h) */

                    #define safe_malloc(siz e) \
                    safe_malloc_ (size, __FILE__, __LINE__)

                    void *safe_malloc_ (size_t size, char const *file, int line);

                    /* implementation (.c) */

                    void *safe_malloc_ (size_t size, char const *file, int line)
                    {
                    void *p = malloc(size);

                    if (p == NULL)
                    {
                    fprintf (stderr
                    , "malloc %lu bytes failed at %s:%d\n"
                    , (unsigned long)size
                    , file
                    , line
                    );
                    exit (EXIT_FAILURE);
                    }
                    return p;
                    }

                    --
                    Emmanuel
                    The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
                    The C-library: http://www.dinkumware.com/refxc.html

                    "Clearly your code does not meet the original spec."
                    "You are sentenced to 30 lashes with a wet noodle."
                    -- Jerry Coffin in a.l.c.c++

                    Comment

                    • Emmanuel Delahaye

                      #11
                      Re: malloc error checking

                      Jonathan Burd wrote on 31/12/04 :[color=blue][color=green]
                      >> void *safe_malloc_ (size_t size, char const *file, int line)
                      >> {
                      >> void *p = malloc(size);[/color][/color]

                      <...>
                      [color=blue]
                      > ret isn't defined. He means return p, anyway.[color=green]
                      >> return ret;
                      >> }
                      >>[/color][/color]

                      Absolutely. Correction made.

                      return p;

                      --
                      Emmanuel
                      The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
                      The C-library: http://www.dinkumware.com/refxc.html

                      "Mal nommer les choses c'est ajouter du malheur au
                      monde." -- Albert Camus.

                      Comment

                      • Artie Gold

                        #12
                        Re: malloc error checking

                        Emmanuel Delahaye wrote:[color=blue]
                        > (supersedes <mn.f4417d4c83f e5bea.15512@YOU RBRAnoos.fr>)
                        >
                        > David REsnick wrote on 30/12/04 :
                        >[color=green]
                        >> void *safe_malloc(si ze_t size)
                        >> {
                        >> void *ret = malloc(size);
                        >> if (ret == NULL) {
                        >> fprintf(stderr, "malloc %u bytes failed", (unsigned)size) ;
                        >> exit(EXIT_FAILU RE);
                        >> }
                        >>
                        >> return ret;
                        >> }[/color]
                        >
                        >
                        > I would amend this code this way:
                        >
                        > /* interface (.h) */
                        >
                        > #define safe_malloc(siz e) \
                        > safe_malloc_ (size, __FILE__, __LINE__)
                        >
                        > void *safe_malloc_ (size_t size, char const *file, int line);
                        >
                        > /* implementation (.c) */
                        >
                        > void *safe_malloc_ (size_t size, char const *file, int line)
                        > {
                        > void *p = malloc(size);
                        >
                        > if (p == NULL)
                        > {
                        > fprintf (stderr
                        > , "malloc %lu bytes failed at %s:%d\n"
                        > , (unsigned long)size
                        > , file
                        > , line
                        > );[/color]

                        Ooooh. Not a great idea. If malloc() fails, fprintf (which likely uses
                        malloc() itself) may also fail.
                        [color=blue]
                        > exit (EXIT_FAILURE);
                        > }
                        > return p;
                        > }
                        >[/color]
                        HTH,
                        --ag

                        --
                        Artie Gold -- Austin, Texas
                        http://it-matters.blogspot.com (new post 12/5)

                        Comment

                        • Emmanuel Delahaye

                          #13
                          Re: malloc error checking

                          Artie Gold wrote on 01/01/05 :[color=blue][color=green]
                          >> void *safe_malloc_ (size_t size, char const *file, int line)
                          >> {
                          >> void *p = malloc(size);
                          >>
                          >> if (p == NULL)
                          >> {
                          >> fprintf (stderr
                          >> , "malloc %lu bytes failed at %s:%d\n"
                          >> , (unsigned long)size
                          >> , file
                          >> , line
                          >> );[/color]
                          >
                          > Ooooh. Not a great idea. If malloc() fails, fprintf (which likely uses
                          > malloc() itself) may also fail.[/color]

                          Do you have any evidence of this ? Do you meant that the only option is

                          exit(EXIT_FAILU RE);

                          --
                          Emmanuel
                          The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
                          The C-library: http://www.dinkumware.com/refxc.html

                          "Clearly your code does not meet the original spec."
                          "You are sentenced to 30 lashes with a wet noodle."
                          -- Jerry Coffin in a.l.c.c++

                          Comment

                          • Chris Croughton

                            #14
                            Re: malloc error checking

                            On Fri, 31 Dec 2004 22:23:46 -0600, Artie Gold
                            <artiegold@aust in.rr.com> wrote:
                            [color=blue]
                            > Emmanuel Delahaye wrote:[color=green]
                            >>
                            >> void *safe_malloc_ (size_t size, char const *file, int line)
                            >> {
                            >> void *p = malloc(size);
                            >>
                            >> if (p == NULL)
                            >> {
                            >> fprintf (stderr
                            >> , "malloc %lu bytes failed at %s:%d\n"
                            >> , (unsigned long)size
                            >> , file
                            >> , line
                            >> );[/color]
                            >
                            > Ooooh. Not a great idea. If malloc() fails, fprintf (which likely uses
                            > malloc() itself) may also fail.[/color]

                            And the ceiling may fall in and crush the hard disk. That isn't a good
                            reason to not output diagnostics. What would you suggest instead?
                            Just:
                            [color=blue][color=green]
                            >> exit (EXIT_FAILURE);[/color][/color]

                            with no explanation?

                            (There are many occasions when malloc may fail but fprintf will work
                            fine -- when the I/O buffers are already allocated, when the size
                            requested is unreasonably big, etc. If fprintf does fail, it is likely
                            to do so with a code dump which can be inspected, whereas just doing
                            exit will not be trapped.)

                            Chris C

                            Comment

                            • Artie Gold

                              #15
                              Re: malloc error checking

                              Chris Croughton wrote:[color=blue]
                              > On Fri, 31 Dec 2004 22:23:46 -0600, Artie Gold
                              > <artiegold@aust in.rr.com> wrote:
                              >
                              >[color=green]
                              >>Emmanuel Delahaye wrote:
                              >>[color=darkred]
                              >>>void *safe_malloc_ (size_t size, char const *file, int line)
                              >>>{
                              >>> void *p = malloc(size);
                              >>>
                              >>> if (p == NULL)
                              >>> {
                              >>> fprintf (stderr
                              >>> , "malloc %lu bytes failed at %s:%d\n"
                              >>> , (unsigned long)size
                              >>> , file
                              >>> , line
                              >>> );[/color]
                              >>
                              >>Ooooh. Not a great idea. If malloc() fails, fprintf (which likely uses
                              >>malloc() itself) may also fail.[/color]
                              >
                              >
                              > And the ceiling may fall in and crush the hard disk. That isn't a good
                              > reason to not output diagnostics. What would you suggest instead?
                              > Just:
                              >
                              >[color=green][color=darkred]
                              >>> exit (EXIT_FAILURE);[/color][/color]
                              >
                              >
                              > with no explanation?[/color]

                              Point taken.
                              [color=blue]
                              >
                              > (There are many occasions when malloc may fail but fprintf will work
                              > fine -- when the I/O buffers are already allocated, when the size
                              > requested is unreasonably big, etc. If fprintf does fail, it is likely
                              > to do so with a code dump which can be inspected, whereas just doing
                              > exit will not be trapped.)
                              >[/color]
                              It's one of those situations where going into platform-specific-land
                              (using lower level calls) *may* be indicated. But again, I concede your
                              point.

                              --ag
                              --
                              Artie Gold -- Austin, Texas
                              http://it-matters.blogspot.com (new post 12/5)

                              Comment

                              Working...