NULL pointer in overloaded operator delete []

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

    NULL pointer in overloaded operator delete []

    Please read the following code

    class Test{
    public:
    void * operator new [] (size_t t)
    { return malloc(t); }

    void operator delete [] (void *p)
    { free(p); }
    };

    void main () {

    Test *p= 0;

    delete [] p;

    /* What should happen here, Should the call go inside Test::operator
    delete []. Because what I learned from books is that deleting a NULL
    pointer is safe (calling ::operator delete[] on a NULL pointer does
    not crash). But here it causes a crash on Sun CC because it gets
    inside Test::operator delete [] whereas on VC++ and g++ it doesn't.

    Should I put a check in Test::operator delete [] for "p!
    =NULL"? Is Sun CC behaving as per the C++ standard?
    */
    }


    Thanks in advance
  • Victor Bazarov

    #2
    Re: NULL pointer in overloaded operator delete []

    Rahul wrote:
    Please read the following code
    >
    class Test{
    public:
    void * operator new [] (size_t t)
    { return malloc(t); }
    >
    void operator delete [] (void *p)
    { free(p); }
    };
    >
    void main () {
    >
    Test *p= 0;
    >
    delete [] p;
    >
    /* What should happen here, Should the call go inside Test::operator
    delete []. Because what I learned from books is that deleting a NULL
    pointer is safe (calling ::operator delete[] on a NULL pointer does
    not crash). But here it causes a crash on Sun CC because it gets
    inside Test::operator delete [] whereas on VC++ and g++ it doesn't.
    >
    Should I put a check in Test::operator delete [] for "p!
    =NULL"? Is Sun CC behaving as per the C++ standard?
    The behaviour of your program is undefined. 'main' must return the type
    'int':

    int main() {

    Seriously, though, everything should be OK because 'free' is explicitly
    specified as a NOP if its argument is a null pointer.

    You need to investigate further why on Sun it doesn't go into the
    overloaded operator delete[]. And even if you don't overload, the
    deletion (using 'delete' or 'delete[]') is explicitly defined as OK if
    the argument is a null pointer.
    */
    }
    >
    >
    Thanks in advance
    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask

    Comment

    • Andrey Tarasevich

      #3
      Re: NULL pointer in overloaded operator delete []

      Rahul wrote:
      Please read the following code
      >
      class Test{
      public:
      void * operator new [] (size_t t)
      { return malloc(t); }
      >
      void operator delete [] (void *p)
      { free(p); }
      };
      >
      void main () {
      >
      Test *p= 0;
      >
      delete [] p;
      >
      /* What should happen here, Should the call go inside Test::operator
      delete []. Because what I learned from books is that deleting a NULL
      pointer is safe (calling ::operator delete[] on a NULL pointer does
      not crash). But here it causes a crash on Sun CC because it gets
      inside Test::operator delete [] whereas on VC++ and g++ it doesn't.
      >
      Should I put a check in Test::operator delete [] for "p!
      =NULL"? Is Sun CC behaving as per the C++ standard?
      */
      }
      Unfortunately, the language specification is (was?) not sufficiently
      clear on whether the control should go into the overloaded 'operator
      delete' when the delete-expression is invoked on the null-pointer of
      corresponding type, even though the standard does say that
      delete-expression on null-pointer is a no-op. Apparently Sun compiler
      thinks that it should be called.

      Meanwhile, I don't understand why it crashes on Sun, even if it gets
      into the above 'operator delete[]'. The standard 'free' function is also
      a no-op on a null-pointer argument. If it crashes, that would mean that
      there's a bug in Sun's 'free' implementation.

      BTW, how do you know that VC and g++ don't call it? You really checked
      it or you just assumed it because it didn't crash?

      --
      Best regards,
      Andrey Tarasevich

      Comment

      • Rahul

        #4
        Re: NULL pointer in overloaded operator delete []

        On Nov 13, 8:13 pm, Andrey Tarasevich <andreytarasev. ..@hotmail.com>
        wrote:
        Rahul wrote:
        Please read the following code
        >
        class Test{
        public:
                void * operator new [] (size_t t)
                {       return malloc(t);       }
        >
                void operator delete [] (void *p)
                {        free(p);       }
        };
        >
        void main () {
        >
        Test *p= 0;
        >
        delete [] p;
        >
        /* What should happen here, Should the call go inside Test::operator
        delete []. Because what I  learned from books is that deleting a NULL
        pointer is safe (calling ::operator delete[] on a NULL pointer does
        not crash). But here it causes a crash on Sun CC because it gets
        inside Test::operator delete [] whereas on VC++ and g++ it doesn't.
        >
                Should I put a check in Test::operator delete [] for "p!
        =NULL"? Is Sun CC behaving as per the C++ standard?
        */
        }
        >
        Unfortunately, the language specification is (was?) not sufficiently
        clear on whether the control should go into the overloaded 'operator
        delete' when the delete-expression is invoked on the null-pointer of
        corresponding type, even though the standard does say that
        delete-expression on null-pointer is a no-op. Apparently Sun compiler
        thinks that it should be called.
        >
        Meanwhile, I don't understand why it crashes on Sun, even if it gets
        into the above 'operator delete[]'. The standard 'free' function is also
        a no-op on a null-pointer argument. If it crashes, that would mean that
        there's a bug in Sun's 'free' implementation.
        >
        BTW, how do you know that VC and g++ don't call it? You really checked
        it or you just assumed it because it didn't crash?
        >
        --
        Best regards,
        Andrey Tarasevich- Hide quoted text -
        >
        - Show quoted text -
        Hi,

        Sorry for my ignorance. But that is just a dummy code which I wrote
        quickly, so actually its "int main" only
        and the operator delete [] does not call free(), It manages a double
        linked list internally and de-references the pointer p before actually
        freeing the memory. Which causes a crash.

        So I wanted to know if I should put a platform specific NULL check in
        operator delete [] OR should make it general. Doing that would
        penalize other platforms un-necessarily, of-course the cost is not
        much considering the whole application. But my point is, why to
        penalize other platforms if they are behaving as per the standard (If
        at all they are ).”

        Comment

        • blargg

          #5
          Re: NULL pointer in overloaded operator delete []

          Rahul wrote:
          Rahul wrote:
          class Test{
          public:
          void * operator new [] (size_t t)
          { return malloc(t); }
          void operator delete [] (void *p)
          { free(p); }
          };
          void main () {
          Test *p= 0;
          delete [] p;
          /* What should happen here, Should the call go inside Test::operator
          delete []. Because what I learned from books is that deleting a NULL
          pointer is safe (calling ::operator delete[] on a NULL pointer does
          not crash). But here it causes a crash on Sun CC because it gets
          inside Test::operator delete [] whereas on VC++ and g++ it doesn't.
          Should I put a check in Test::operator delete [] for "p=
          !
          =NULL"? Is Sun CC behaving as per the C++ standard?
          */
          }
          [...]
          Sorry for my ignorance. But that is just a dummy code which I wrote
          quickly, so actually its "int main" only
          and the operator delete [] does not call free(), It manages a double
          linked list internally and de-references the pointer p before actually
          freeing the memory. Which causes a crash.
          Which means your code may be at fault.
          So I wanted to know if I should put a platform specific NULL check in
          operator delete [] OR should make it general. Doing that would
          penalize other platforms un-necessarily, of-course the cost is not
          much considering the whole application. But my point is, why to
          penalize other platforms if they are behaving as per the standard (If
          at all they are ).
          You should first write a test program to see what is really happening on
          your platform. First, see if free( 0 ) is crashing:

          int main() { free( 0 ); }

          then see if NULL is being passed to your operator delete []:

          class Test {
          public:
          void* operator new [] ( size_t s ) throw() { return malloc( s ); }
          void operator delete [] ( void* p ) throw() { assert( p ); free( p ); }
          };

          int main()
          {
          Test* p = 0;
          delete [] p;
          }

          Once you know what's going on, you can decide how to handle your
          compiler's non-conformance (assuming there is any).

          Comment

          • Andrey Tarasevich

            #6
            Re: NULL pointer in overloaded operator delete []

            Rahul wrote:
            >
            So I wanted to know if I should put a platform specific NULL check in
            operator delete [] OR should make it general. Doing that would
            penalize other platforms un-necessarily, of-course the cost is not
            much considering the whole application. But my point is, why to
            penalize other platforms if they are behaving as per the standard (If
            at all they are ).”
            I would recommend you to pot a _general_ null-pointer check into your
            overloaded 'operator delete[]'. The reason for this is that technically
            'operator delete[]' is by itself a standalone self-sufficient
            resource-deallocation function. It can actually be called explicitly by
            the user, should the need arise. I'd say that there's a de-facto
            standard (or at least a widespread and accepted practice) to write all
            resource deallocation functions so that they permit a null argument and
            act as a no-op in that case.

            Of course, I understand perfectly well that overloaded 'operator delete'
            is not normally intended to be used as a self-sufficient function. But
            nevertheless it feels like a good idea to preserve the null->no-op
            guarantee for this function as well. (Standard library-provided versions
            do that, BTW.) The overhead of doing the null check is less than
            negligible, so I'd remove the issue of "penalizing the other platforms"
            from consideration entirely.

            --
            Best regards,
            Andrey Tarasevich

            Comment

            • James Kanze

              #7
              Re: NULL pointer in overloaded operator delete []

              On Nov 13, 2:50 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
              Rahul wrote:
              Please read the following code
              class Test{
              public:
                      void * operator new [] (size_t t)
                      {       return malloc(t);       }
              >
                      void operator delete [] (void *p)
                      {        free(p);       }
              };
              void main () {
              Test *p= 0;
              delete [] p;
              /* What should happen here,  Should the call go inside Test::operator
              delete []. Because what I  learned from books is that deleting a NULL
              pointer is safe (calling ::operator delete[] on a NULL pointer does
              not crash). But here it causes a crash on Sun CC because it gets
              inside Test::operator delete [] whereas on VC++ and g++ it doesn't.
                      Should I put a check in Test::operator delete [] for "p!
              =NULL"? Is Sun CC behaving as per the C++ standard?
              The behaviour of your program is undefined.  'main' must
              return the type 'int':
              Not undefined. It's an error which requires a diagnosis.

              Of course, that is completely orthogonal to his question.
                  int main() {
              Seriously, though, everything should be OK because 'free' is
              explicitly specified as a NOP if its argument is a null
              pointer.
              You need to investigate further why on Sun it doesn't go into
              the overloaded operator delete[].  And even if you don't
              overload, the deletion (using 'delete' or 'delete[]') is
              explicitly defined as OK if the argument is a null pointer.
              It's still the responisiblity of operator delete (or delete[])
              to check; the standard doesn't guarantee that it won't be given
              a null pointer; the standard requires that it be a no-op if
              given a null pointer.

              But of course, all he's doing is calling free() with the pointer,
              and free() is guaranteed to be a no-op when given a null
              pointer, so his implementation meets the requirements.

              --
              James Kanze (GABI Software) email:james.kan ze@gmail.com
              Conseils en informatique orientée objet/
              Beratung in objektorientier ter Datenverarbeitu ng
              9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

              Comment

              • James Kanze

                #8
                Re: NULL pointer in overloaded operator delete []

                On Nov 13, 4:13 pm, Andrey Tarasevich <andreytarasev. ..@hotmail.com>
                wrote:
                Rahul wrote:
                Please read the following code
                class Test{
                public:
                        void * operator new [] (size_t t)
                        {       return malloc(t);       }
                >
                        void operator delete [] (void *p)
                        {        free(p);       }
                };
                void main () {
                Test *p= 0;
                delete [] p;
                /* What should happen here, Should the call go inside Test::operator
                delete []. Because what I  learned from books is that deleting a NULL
                pointer is safe (calling ::operator delete[] on a NULL pointer does
                not crash). But here it causes a crash on Sun CC because it gets
                inside Test::operator delete [] whereas on VC++ and g++ it doesn't.
                        Should I put a check in Test::operator delete [] for "p!
                =NULL"? Is Sun CC behaving as per the C++ standard?
                */
                }
                Unfortunately, the language specification is (was?) not
                sufficiently clear on whether the control should go into the
                overloaded 'operator delete' when the delete-expression is
                invoked on the null-pointer of corresponding type, even though
                the standard does say that delete-expression on null-pointer
                is a no-op. Apparently Sun compiler thinks that it should be
                called.
                Or that the implementation is allowed to call it. According to
                the latest draft, "The value of the first argument supplied to a
                deallocation function may be a null pointer value; if so, and if
                the deallocation function is one supplied in the standard
                library, the call has no effect." I'm not quite sure what the
                implications of that "is one supplied in the standard library"
                are meant to be---taken literally, since his function is not one
                provided by the standard library, the sentence wouldn't seem to
                apply. But somehow, that doesn't make sense.

                It may be worth raising the issue with the committee.

                --
                James Kanze (GABI Software) email:james.kan ze@gmail.com
                Conseils en informatique orientée objet/
                Beratung in objektorientier ter Datenverarbeitu ng
                9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                Comment

                • Andrey Tarasevich

                  #9
                  Re: NULL pointer in overloaded operator delete []

                  James Kanze wrote:
                  >
                  It may be worth raising the issue with the committee.
                  >
                  It has been raised already



                  --
                  Best regards,
                  Andrey Tarasevich

                  Comment

                  Working...