[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

can a const pointer be deleted?

abir

12/2/2008 1:55:00 PM

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
3 Answers

Maxim Yegorushkin

12/2/2008 3:06:00 PM

0

On Dec 2, 1:55 pm, abir <abirba...@gmail.com> 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

abir

12/3/2008 5:01:00 AM

0

On Dec 2, 8:05 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
wrote:
> On Dec 2, 1:55 pm, abir <abirba...@gmail.com> 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/librar...(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

James Kanze

12/3/2008 9:30:00 AM

0

On Dec 2, 4:05 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
wrote:
> On Dec 2, 1:55 pm, abir <abirba...@gmail.com> 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:james.kanze@gmail.com
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