can a const pointer be deleted?

Discussion in 'C++' started by abir, Dec 2, 2008.

  1. abir

    abir Guest

    Hi,
    In the std containers erase takes a const_iterator.
    I have my own container and there const_iterator is a const pointer
    to the item.
    I want to free the memory for the item on erase (i.e both destroy &
    deallocate).
    However deallocate function for allocator (and so delete, free etc)
    takes a pointer rather than
    a const pointer. Is that mean i have to cast it back to a pointer?

    I was looking at std::list. There even a const_iterator returns a non
    const node pointer (not very sure though).
    Also how this works ? does the operator delete automatically cast it
    to a non const type ?
    const testobj* to = new testobj(1,1);
    delete to;

    In C, while this works
    char* ch = (char*)std::malloc(5);
    std::free(ch);
    for a const pointer i explicitly need to cast it back like,
    const char* ch = (const char*)std::malloc(5);
    std::free((char*)ch);//or std::free(void*)ch);

    Thanks
    abir
     
    abir, Dec 2, 2008
    #1
    1. Advertising

  2. On Dec 2, 1:55 pm, abir <> wrote:
    > Hi,
    >   In the std containers erase takes a const_iterator.


    This is not so.

    In std containers erase member function is a non-const member
    function, because it changes the container contents. It would not be
    logical for that function to accept const_iterator.

    >   I have my own container and there const_iterator is a const pointer
    > to the item.
    >   I want to free the memory for the item on erase (i.e both destroy &
    > deallocate).
    >  However deallocate function for allocator (and so delete, free etc)
    > takes a pointer rather than
    >  a const pointer. Is that mean i have to cast it back to a pointer?


    Make your_container::erase() accept non-const iterators.

    >  I was looking at std::list. There even a const_iterator returns a non
    > const node pointer (not very sure though).
    >  Also how this works ? does the operator delete automatically cast it
    > to a non const type ?
    > const testobj* to = new testobj(1,1);
    > delete to;


    There are two different things in C++ named delete: a) delete-
    expression; b) operator delete. Here you are using delete-expression
    and it ignores const-ness and volatile-ness. What delete-expression a)
    does is it calls the destructor of the object and then invokes
    operator delete b).

    > In C, while this works
    > char* ch = (char*)std::malloc(5);
    >     std::free(ch);
    > for a const pointer i explicitly need to cast it back like,
    > const char* ch = (const char*)std::malloc(5);
    >  std::free((char*)ch);//or std::free(void*)ch);


    In C++ the equivalents of malloc/free are operator new/delete, not new/
    delete-expression:

    #include <new>
    int main()
    {
    char const* c = (char const*)operator new(5);
    operator delete((void*)c); // need a cast here
    }

    --
    Max
     
    Maxim Yegorushkin, Dec 2, 2008
    #2
    1. Advertising

  3. abir

    abir Guest

    On Dec 2, 8:05 pm, Maxim Yegorushkin <>
    wrote:
    > On Dec 2, 1:55 pm, abir <> wrote:
    >
    > > Hi,
    > > In the std containers erase takes a const_iterator.

    >
    > This is not so.
    >
    > In std containers erase member function is a non-const member
    > function, because it changes the container contents. It would not be
    > logical for that function to accept const_iterator.
    >

    Though the MSDN document (I am using VC9 express) says it it an
    iterator
    http://msdn.microsoft.com/en-us/library/ceh559x2(VS.80).aspx
    and SGI is saying the same, the code says it is an const iterator and
    thus,
    std::vector<int> v;
    v.push_back(1);
    const std::vector<int>& cv = v;
    std::cout<<typeid(cv.begin()).name()<<"\n";
    v.erase(cv.begin());
    This code runs perfectly, and indeed cv.begin() is const_iterator and
    i think
    it is not possible to convert a const_iterator to iterator, though the
    other way is possible.
    So not sure if i am missing something or it is bug from msvc side.
    Will check it on gcc.
    > > I have my own container and there const_iterator is a const pointer
    > > to the item.
    > > I want to free the memory for the item on erase (i.e both destroy &
    > > deallocate).
    > > However deallocate function for allocator (and so delete, free etc)
    > > takes a pointer rather than
    > > a const pointer. Is that mean i have to cast it back to a pointer?

    >
    > Make your_container::erase() accept non-const iterators.
    >

    That is what i do. But my point is, if const pointer can be destroyed
    (though can't be modified)
    so why can't const_iterator do the same?
    > > I was looking at std::list. There even a const_iterator returns a non
    > > const node pointer (not very sure though).
    > > Also how this works ? does the operator delete automatically cast it
    > > to a non const type ?
    > > const testobj* to = new testobj(1,1);
    > > delete to;

    >
    > There are two different things in C++ named delete: a) delete-
    > expression; b) operator delete. Here you are using delete-expression
    > and it ignores const-ness and volatile-ness. What delete-expression a)
    > does is it calls the destructor of the object and then invokes
    > operator delete b).
    >
    > > In C, while this works
    > > char* ch = (char*)std::malloc(5);
    > > std::free(ch);
    > > for a const pointer i explicitly need to cast it back like,
    > > const char* ch = (const char*)std::malloc(5);
    > > std::free((char*)ch);//or std::free(void*)ch);

    >
    > In C++ the equivalents of malloc/free are operator new/delete, not new/
    > delete-expression:
    >
    > #include <new>
    > int main()
    > {
    > char const* c = (char const*)operator new(5);
    > operator delete((void*)c); // need a cast here
    > }
    >

    I understand that. What i want to know whether delete expression after
    calling destructor
    implicitly cast the const pointer to non const before calling delete
    operator? as delete operator
    takes a void* (and not a const void*) and the pointer available after
    destruction is const T* (T is the object type) which can be converted
    to const void* but not to void* in 'ordinary cases'.
    It seems delete expression, as you said does that extra thing to
    remove const-ness and volatile
    from the pointer before calling delete operator (Though i don't know
    why!).

    Thanks for reply.
    abir
    > --
    > Max
     
    abir, Dec 3, 2008
    #3
  4. abir

    James Kanze Guest

    On Dec 2, 4:05 pm, Maxim Yegorushkin <>
    wrote:
    > On Dec 2, 1:55 pm, abir <> wrote:


    > > In the std containers erase takes a const_iterator.


    > This is not so.


    > In std containers erase member function is a non-const member
    > function, because it changes the container contents. It would
    > not be logical for that function to accept const_iterator.


    Why not? It don't modify anything through the iterator; the
    iterator is only used for determining the position.

    The original standard required iterator; this was recognized as
    an error, and has been corrected; insert and erase now take
    const_iterator for the position argument.

    > > I have my own container and there const_iterator is a const
    > > pointer to the item. I want to free the memory for the item
    > > on erase (i.e both destroy & deallocate). However
    > > deallocate function for allocator (and so delete, free etc)
    > > takes a pointer rather than a const pointer. Is that mean i
    > > have to cast it back to a pointer?


    > Make your_container::erase() accept non-const iterators.


    In this case, I'd use const_cast, if nothing else was readily
    available. You're in a non-const function of the container, so
    you have a right to modify it, so once you've asserted that the
    iterator does point into this container (and not some other
    container), I seen no harm in de-constifying it. (A comment
    would be in order, however.)

    > > I was looking at std::list. There even a const_iterator
    > > returns a non const node pointer (not very sure though).
    > > Also how this works ?


    The const-ness that the compiler understands is very
    superficial. The nodes aren't part of the object, as far as the
    compiler is concerned, so even a const member function (e.g. the
    one which returned the const_iterator) can obtain non-const
    pointers to the node. After that, it's the responsibility of
    the classes involved (the container, iterators, nodes, etc.) to
    ensure that this lack of const doesn't "leak" out at the
    interface somewhere.

    > > does the operator delete automatically cast it to a non
    > > const type ?
    > > const testobj* to = new testobj(1,1);
    > > delete to;


    > There are two different things in C++ named delete: a) delete-
    > expression; b) operator delete. Here you are using
    > delete-expression and it ignores const-ness and volatile-ness.
    > What delete-expression a) does is it calls the destructor of
    > the object and then invokes operator delete b).


    > > In C, while this works
    > > char* ch = (char*)std::malloc(5);
    > > std::free(ch);
    > > for a const pointer i explicitly need to cast it back like,
    > > const char* ch = (const char*)std::malloc(5);
    > > std::free((char*)ch);//or std::free(void*)ch);


    > In C++ the equivalents of malloc/free are operator new/delete,
    > not new/ delete-expression:
    >
    > #include <new>
    > int main()
    > {
    > char const* c = (char const*)operator new(5);
    > operator delete((void*)c); // need a cast here
    > }


    The main argument here is that since const-ness doesn't prevent
    calling the destructor in something like:

    void
    f()
    {
    MyClass const object ;
    // ...
    // object.~MyClass() called here.
    }

    it shouldn't be an issue in:

    void
    f()
    {
    MyClass const* pObject = new MyClass ;
    // ...
    delete pObject ;
    }

    (That's the argument given. Up to you to decide whether it is
    convincing or not.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Dec 3, 2008
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. coala
    Replies:
    3
    Views:
    412
    coala
    Sep 6, 2006
  2. coala
    Replies:
    1
    Views:
    613
    Victor Bazarov
    Sep 6, 2006
  3. Javier
    Replies:
    2
    Views:
    621
    James Kanze
    Sep 4, 2007
  4. Disc Magnet
    Replies:
    1
    Views:
    654
    Ian Collins
    May 6, 2010
  5. Chumley the Walrus
    Replies:
    2
    Views:
    275
    Tom Gosselin
    Aug 10, 2004
Loading...

Share This Page