Topic: Using the pointer after delete


Author: ark@acm.org ("Andrew Koenig")
Date: Sun, 5 Dec 2004 00:47:39 GMT
Raw View
<kanze@gabi-soft.fr> wrote in message
news:d6652001.0412010821.461147e7@posting.google.com...
> ark@acm.org ("Andrew Koenig") wrote in message
> news:<OuJqd.72125$7i4.16037@bgtnsc05-news.ops.worldnet.att.net>...
>> "Alberto Barbati" <AlbertoBarbati@libero.it> wrote in message
>> news:cFDqd.56348$Ni.1950485@twister1.libero.it...
>> Kim, Seungtai wrote:
>
>> >Please notice that "delete p" does *not* change the value stored in
>> >p, it simply makes that value (and any copy of it) unusable.
>
>> How would you write a program that would assuredly detect whether
>> "delete p" changes the value stored in p?  I can't think of a way to
>> do it.
>
>    unsigned char buf[ sizeof( char* ) ] ;
>    char* p = new char ;
>    memcpy( buf, &p, sizeof( char* ) ) ;
>    delete p ;
>    std::cout << memcmp( buf, &p, sizeof( char* ) ) << std::endl ;
>
> First, I think you'll agree that that there is no undefined behavior in
> the above.  But is the value output to cout guaranteed to be 0, or not?

I think that the call to memcmp evokes undefined behavior because it
attempts to access the contents of p.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Sun, 5 Dec 2004 01:08:52 GMT
Raw View
"Arijit" <pal_ari@yahoo.co.in> wrote in message
news:31eo9dF3aogqnU1@individual.net...

> Does the following work ?
>
> int main()
> {
>   int *p = new int;
>   cout << p << endl;
>   delete p;
>
>   for(int i=0;i< sizeof(int*);++i)
>     cout << *(reinterpret_cast<char*>(&p)+i);
> }
>
> It doesn't use the value of p after its deleted directly.
>
> Or if I use memcpy on (char*)(&p) to copy the contents of p. I don't use
> value of p. Will it work ?

If you use reinterpret_cast or memcpy, you are placing yourself in the
implementation's hands.  Whether it works is up to the implementation.  So
you can't be assured that it will work.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Sun, 5 Dec 2004 02:04:28 GMT
Raw View
"James Kuyper" <kuyper@wizard.net> wrote in message
news:8b42afac.0412040855.16d902d7@posting.google.com...

> I'd report a bug in the compiler to the vendor. The memory containing
> the representation of 'p' is not deallocated by 'delete p', unless p
> happens to stored inside the same memory allocation that p points at.
> That's certainly possible, but it's not true in general.

You wouldn't get very far.  Saying "delete p" invalidates p, so that any
subsequent use of that value, including copying it or inspecting it in any
way, evokes undefined behavior.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pal_ari@yahoo.co.in (Arijit)
Date: Sun, 5 Dec 2004 09:36:14 GMT
Raw View
James Kuyper wrote:

> Note: what you're doing doesn't tell us whether the value of 'p'
> changed; it can only tell us whether the representation of 'p'
> changed. There's a mapping between representation and value, and that
> mapping can change as the result of the execution of a delete
> expression. I don't believe that 'delete p' is allowed to change the
> representation, but I'm sure it can change the value.

If the bitwise representation of two objects are the same, how can their
values be different ? I am assuming that you are not referring to
paging, because that works transparently to the program anyway.

An example demonstrating your point would help.

-Arijit

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pal_ari@yahoo.co.in (Arijit)
Date: Sun, 5 Dec 2004 09:36:45 GMT
Raw View
Andrew Koenig wrote:

> I think that the call to memcmp evokes undefined behavior because it
> attempts to access the contents of p.

But memcmp is a library function. So it is allowed to use special
tricks. In fact, it need not even be implemented in C++.

What I mean is that we shouldn't consider how memcmp does its job. I
pass memcmp a valid pointer, and it shouldn't result in UB.

-Arijit

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Sun, 5 Dec 2004 19:46:27 GMT
Raw View
In article <31fga0F392jluU1@individual.net>, Arijit
<pal_ari@yahoo.co.in> writes
>What I mean is that we shouldn't consider how memcmp does its job. I
>pass memcmp a valid pointer, and it shouldn't result in UB.

Absolutely, but if you try to convert an indeterminate pointer value in
order to pass it to memcmp, you are on your own and the language is not
required to help you.


--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Sun, 5 Dec 2004 19:54:22 GMT
Raw View
In article <31fg2fF393a33U1@individual.net>, Arijit
<pal_ari@yahoo.co.in> writes
>If the bitwise representation of two objects are the same, how can
>their values be different ? I am assuming that you are not referring to
>paging, because that works transparently to the program anyway.

Because value depends on both the bit pattern and the context. In some
cases there is more than one representation of a value, in other cases
there is more than one value for a bit-pattern. Indeed, the latter is
normal. Part of the context for determining the value is the type
associated with the bit pattern, another part includes such things as
whether a pointer is currently valid or not.


--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: musiphil@bawi.org (Seungbeom Kim)
Date: Mon, 6 Dec 2004 04:32:13 GMT
Raw View
Andrew Koenig wrote:
> <kanze@gabi-soft.fr> wrote in message
> news:d6652001.0412010821.461147e7@posting.google.com...
>>
>>   unsigned char buf[ sizeof( char* ) ] ;
>>   char* p = new char ;
>>   memcpy( buf, &p, sizeof( char* ) ) ;
>>   delete p ;
>>   std::cout << memcmp( buf, &p, sizeof( char* ) ) << std::endl ;
>>
>>First, I think you'll agree that that there is no undefined behavior in
>>the above.  But is the value output to cout guaranteed to be 0, or not?
>
> I think that the call to memcmp evokes undefined behavior because it
> attempts to access the contents of p.

As long as the code is treating the contents of p not as a pointer value
but as a sequence of byte values in raw memory, I wonder how that could
or whether it really does cause a problem (including UB).

--
Seungbeom Kim

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Mon, 6 Dec 2004 04:32:20 GMT
Raw View
"Arijit" <pal_ari@yahoo.co.in> wrote in message
news:31fga0F392jluU1@individual.net...

> What I mean is that we shouldn't consider how memcmp does its job. I pass
> memcmp a valid pointer, and it shouldn't result in UB.

But you are passing it an invalid pointer, namely one that used to point to
memory that has been freed.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rtw@freenet.co.uk (Rob Williscroft)
Date: Mon, 6 Dec 2004 17:11:46 GMT
Raw View
Francis Glassborow wrote in news:CYGf4iBHWusBFw$4@robinton.demon.co.uk in
comp.std.c++:

> In article <31fga0F392jluU1@individual.net>, Arijit
> <pal_ari@yahoo.co.in> writes
>>What I mean is that we shouldn't consider how memcmp does its job. I
>>pass memcmp a valid pointer, and it shouldn't result in UB.
>
> Absolutely, but if you try to convert an indeterminate pointer value in
> order to pass it to memcmp, you are on your own and the language is not
> required to help you.
>
>

This is very confusing:

#include <cstdlib>

int main()
{
  char buf[ sizeof( int * ) ];
  int *p = new int;
  std::memcpy( buf, &p, sizeof( buf ) );
  delete p;

  bool b = std::memcmp( buf, &p, sizeof( buf ) );
}

There aren't any indeterminate pointer values above.

So whats the consensus, is that the value of b is unknown or is it
the more general form of UB, the call to std::memcmp is UB and
anything can happen ?

Rob.
--
http://www.victim-prime.dsl.pipex.com/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Mon, 6 Dec 2004 11:12:11 CST
Raw View
"Andrew Koenig" wrote:
> "Arijit" <pal_ari@yahoo.co.in> wrote in message
> news:31fga0F392jluU1@individual.net...

> > What I mean is that we shouldn't consider how memcmp does its job.
I
> > pass memcmp a valid pointer, and it shouldn't result in UB.

> But you are passing it an invalid pointer, namely one that used to
> point to memory that has been freed.

The pointer I passed to memcmp was the address of an object on the
stack, not a pointer to memory that has been freed.  The object on the
stack was a pointer to memory that has been freed, but I never access
its value -- just the underlying raw memory.

And I'm getting more and more confused.  Either you've misread my
example, or there's something I'm not understanding, because your
answers don't seem to be addressing my example.

--
James Kanze           GABI Software         http://www.gabi-soft.fr
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


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jdennett@acm.org (James Dennett)
Date: Mon, 6 Dec 2004 18:59:47 GMT
Raw View
Andrew Koenig wrote:
> "Arijit" <pal_ari@yahoo.co.in> wrote in message
> news:31fga0F392jluU1@individual.net...
>
>
>>What I mean is that we shouldn't consider how memcmp does its job. I pass
>>memcmp a valid pointer, and it shouldn't result in UB.
>
>
> But you are passing it an invalid pointer, namely one that used to point to
> memory that has been freed.

I think he's talking about passing a pointer to (a pointer
that used to point to memory that has now been freed), rather
than passing the pointer to the freed memory.  But it's all
rather unclear.

-- James

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nospam@pop.ucsd.edu ("Thomas Mang")
Date: Mon, 6 Dec 2004 18:59:50 GMT
Raw View
""Andrew Koenig"" <ark@acm.org> schrieb im Newsbeitrag
news:sCFsd.1035488$Gx4.734254@bgtnsc04-news.ops.worldnet.att.net...
> "Arijit" <pal_ari@yahoo.co.in> wrote in message
> news:31fga0F392jluU1@individual.net...
>
> > What I mean is that we shouldn't consider how memcmp does its job. I
pass
> > memcmp a valid pointer, and it shouldn't result in UB.
>
> But you are passing it an invalid pointer, namely one that used to point
to
> memory that has been freed.


I can't see how James passed memcmp an invalid pointer. He applied operator&
to the indeterminate pointer value, which results IMHO in a valid pointer.
Once memcmp is called I think we are safe (I think the description on memcmp
is clear).

What I am not sure about is whether applying adress-of operator to an
indeterminate value is safe. Personally, I'd say yes but, well, I think I
wouldn't bet.


Thomas


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nagle@animats.com (John Nagle)
Date: Mon, 6 Dec 2004 19:00:06 GMT
Raw View
Andrew Koenig wrote:

> "James Kuyper" <kuyper@wizard.net> wrote in message
> news:8b42afac.0412040855.16d902d7@posting.google.com...
>
>
>>I'd report a bug in the compiler to the vendor. The memory containing
>>the representation of 'p' is not deallocated by 'delete p', unless p
>>happens to stored inside the same memory allocation that p points at.
>>That's certainly possible, but it's not true in general.
>
>
> You wouldn't get very far.  Saying "delete p" invalidates p, so that any
> subsequent use of that value, including copying it or inspecting it in any
> way, evokes undefined behavior.

    There's been at least one implementation where pointers contained
an address and a serial number.  This allows full pointer validation.

    Here's how it's implemented.

    For each pointer, you first find the beginning of the object
into which it points.  This requires a memory allocation scheme
like that used by Boehm's collector, where each memory page contains
only one size of object.  So you break a pointer down into page number
and offset, look up the block size for the page number in a table
indexed by page number and reduce the pointer modulo the block
size.  You now have the beginning address of the block.

    In the control information before the block, there is a serial
number, incremented for each allocation and zeroed on release.
A stale pointer can thus be detected.

    Incrementing off the end of a block is also detected.  Garbage
pointers are detected.  If the control information for a block
holds type information, type errors can be detected, even
after casts. Essentially, almost all of the undefined
behavior associated with pointers becomes detected errors.
This is the gold standard of pointer validation.

    Given this type of validation, with validation performed at the
points the C++ standard calls for, the pointer abuse being discussed
here would be detected at run time.

    There's an old ACM paper on this.  I wouldn't be surprised if some
CASE tool offers this feature.

    John Nagle
    Animats

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Mon, 6 Dec 2004 23:32:33 GMT
Raw View
<kanze@gabi-soft.fr> wrote in message
news:1102326313.376693.167930@z14g2000cwz.googlegroups.com...

> The pointer I passed to memcmp was the address of an object on the
> stack, not a pointer to memory that has been freed.  The object on the
> stack was a pointer to memory that has been freed, but I never access
> its value -- just the underlying raw memory.

But what happens when memcmp accesses that memory is
implementation-defined -- the standard imposes no requirements on an
implementation to behave in any particular way.

Here's another way to look at it.  Suppose we have a computer that allows
hardware read-protection down to the word level.  Suppose further that I
wish to implement C++ so that for every block of dynamically allocated
memory, there is a hidden data structure that records the address of every
pointer that points to that memory.

Now, suppose that when I delete a block of memory, I arrange for my
implementation to read-protect every pointer that points to that memory.
Assigning a new value to the pointer would undo the read protection, but
until then, every attempt to read the contents of that pointer would result
in a memory-protection fault.

In that case, your call to memcmp would fail because of an attempt to access
read-protected memory.

Are you going to tell me that I'm not allowed to implement C++ that way?  If
not, what part of the standard prohibits it?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Tue, 7 Dec 2004 01:12:32 GMT
Raw View
"Andrew Koenig" wrote:
> "Ben Hutchings" <ben-public-nospam@decadentplace.org.uk> wrote in message
> news:slrncqs11f.5st.ben-public-nospam@decadentplace.org.uk...
>> "Andrew Koenig" wrote:
>>> "Alberto Barbati" <AlbertoBarbati@libero.it> wrote in message
>>> news:cFDqd.56348$Ni.1950485@twister1.libero.it...
>>> Kim, Seungtai wrote:
>>>
>>>>Please notice that "delete p" does *not* change the value stored in p,
>>>> it simply makes that value (and any copy of it) unusable.
>>>
>>> How would you write a program that would assuredly detect whether "delete
>>> p"
>>> changes the value stored in p?  I can't think of a way to do it.
>>
>> You can certainly check whether the bytes of its object representation
>> have changed, which I think is probably what Alberto Barbati meant.
>
> And what do you do if the implementation terminates your program with a
> diagnostic message saying "Sorry, you're not allowed to look at that memory
> any more; you've deallocated it."  ?
>
> That's why I said "assuredly" in my original question.

My code looked at p, not *p.  So if my program was terminated I'd file
a bug report, since the implementation wouldn't be meeting the
requirements in 3.9/2.

--
Ben Hutchings
Design a system any fool can use, and only a fool will want to use it.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Tue, 7 Dec 2004 04:18:04 GMT
Raw View
"Ben Hutchings" <ben-public-nospam@decadentplace.org.uk> wrote in message
news:slrncr9fnr.ji2.ben-public-nospam@decadentplace.org.uk...

>> And what do you do if the implementation terminates your program with a
>> diagnostic message saying "Sorry, you're not allowed to look at that
>> memory
>> any more; you've deallocated it."  ?
>>
>> That's why I said "assuredly" in my original question.
>
> My code looked at p, not *p.  So if my program was terminated I'd file
> a bug report, since the implementation wouldn't be meeting the
> requirements in 3.9/2.

I'll respond to your bug report by changing the diagnostic message slightly:

    Sorry, you're not allowed to look at that pointer any more;
    you invalidated it when you deallocated the memory to which
    it used to point.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Tue, 7 Dec 2004 04:45:14 GMT
Raw View
pal_ari@yahoo.co.in (Arijit) wrote in message
news:<31fg2fF393a33U1@individual.net>...
> James Kuyper wrote:

> > Note: what you're doing doesn't tell us whether the value of 'p'
> > changed; it can only tell us whether the representation of 'p'
> > changed. There's a mapping between representation and value, and
> > that mapping can change as the result of the execution of a delete
> > expression. I don't believe that 'delete p' is allowed to change the
> > representation, but I'm sure it can change the value.

> If the bitwise representation of two objects are the same, how can
> their values be different ?

The value of an object is an interpretation of the bitwise
representation.  To start with, it depends on the type: you'd certainly
agree that the value of the same bitwise representation will differ
depending on whether the type is a float or an int.  In this case, we
have an object whose value is undefined, and for which accessing the
value is undefined behavior.  The object's memory is still allocated,
however, the bits are there, and we can still access the bitwise
representation by means of the standard C++ techniques for accessing
bitwise represntations.

Or at least, that's what I've always thought.  Andy Koenig seems to
think otherwise, and until he's presented his reasons, I'll reserve
judgement.

> I am assuming that you are not referring
> to paging, because that works transparently to the program anyway.

> An example demonstrating your point would help.

An obvious example would be copying a float into an unsigned int on the
majority of 32 bit machines around today.  The bitwise representation of
the two objects will be the same, but the value surely won't be (unless
the float happened to contain a positive 0.0).

The trick with the pointer is that the raw memory (the bitwize
representation) still exists, even if the value of the pointer is
invalid (doesn't exist, in a way, since you can't access it).

--
James Kanze           GABI Software         http://www.gabi-soft.fr
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

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Tue, 7 Dec 2004 04:46:49 GMT
Raw View
"Seungbeom Kim" <musiphil@bawi.org> wrote in message
news:couk2g$440$1@news.Stanford.EDU...

> As long as the code is treating the contents of p not as a pointer value
> but as a sequence of byte values in raw memory, I wonder how that could or
> whether it really does cause a problem (including UB).

The question is not whether it is likely to cause a problem on a particular
implementation;
the question is how much latitude an implementation has to detect
programming errors if it so wishes.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Mon, 6 Dec 2004 22:45:52 CST
Raw View
"Andrew Koenig" wrote:
> "James Kuyper" <kuyper@wizard.net> wrote in message
> news:8b42afac.0412040855.16d902d7@posting.google.com...

> > I'd report a bug in the compiler to the vendor. The memory
> > containing the representation of 'p' is not deallocated by 'delete
> > p', unless p happens to stored inside the same memory allocation
> > that p points at.  That's certainly possible, but it's not true in
> > general.

> You wouldn't get very far.  Saying "delete p" invalidates p, so that
> any subsequent use of that value, including copying it or inspecting
> it in any way, evokes undefined behavior.

Which is the crux of the question.  Is accessing the underlying raw
memory, as an array of unsigned bytes, accessing the value?  I don't
think so; I would consider "accessing the value" to be the lvalue to
rvalue conversion.  And in other places, the C++ standard garantees
that
I can access the raw memory of any object as an array of unsigned char.
(And memcpy is required to copy the raw memory of an object, as if it
were just bytes.)

--
James Kanze           GABI Software         http://www.gabi-soft.fr
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


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Mon, 6 Dec 2004 22:45:35 CST
Raw View
"Andrew Koenig" wrote:
> "Arijit" <pal_ari@yahoo.co.in> wrote in message
> news:31fga0F392jluU1@individual.net...

> > What I mean is that we shouldn't consider how memcmp does its job.
I
> > pass memcmp a valid pointer, and it shouldn't result in UB.

> But you are passing it an invalid pointer, namely one that used to
> point to memory that has been freed.

No I'm not.  I'm passing it the address of an on-stack object.  The
fact
that that object happens to be a pointer which used to point to memory
that has been freed is irrelevant -- the pointer I pass to memcmp is
valid.

--
James Kanze           GABI Software         http://www.gabi-soft.fr
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


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Tue, 7 Dec 2004 15:11:34 GMT
Raw View
Andrew Koenig wrote:
> "Ben Hutchings" <ben-public-nospam@decadentplace.org.uk> wrote in message
> news:slrncr9fnr.ji2.ben-public-nospam@decadentplace.org.uk...
>
>
>>>And what do you do if the implementation terminates your program with a
>>>diagnostic message saying "Sorry, you're not allowed to look at that
>>>memory
>>>any more; you've deallocated it."  ?
>>>
>>>That's why I said "assuredly" in my original question.
>>
>>My code looked at p, not *p.  So if my program was terminated I'd file
>>a bug report, since the implementation wouldn't be meeting the
>>requirements in 3.9/2.
>
>
> I'll respond to your bug report by changing the diagnostic message slightly:
>
>     Sorry, you're not allowed to look at that pointer any more;
>     you invalidated it when you deallocated the memory to which
>     it used to point.

That wouldn't be a good message either, IMHO. 3.9/2 explicitly states
that I shall be able to inspect the underlying representation of p
"whether or not the object [p in this case] holds a valid value".

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Tue, 7 Dec 2004 11:14:29 CST
Raw View
"Andrew Koenig" wrote:
> <kanze@gabi-soft.fr> wrote in message
> news:1102326313.376693.167930@z14g2000cwz.googlegroups.com...

> > The pointer I passed to memcmp was the address of an object on the
> > stack, not a pointer to memory that has been freed.  The object on
> > the stack was a pointer to memory that has been freed, but I never
> > access its value -- just the underlying raw memory.

> But what happens when memcmp accesses that memory is
> implementation-defined -- the standard imposes no requirements on an
> implementation to behave in any particular way.

That's not quite true.  The C standard (included by reference) requires
the implementation to compare the "characters" as "unsigned char"s.

There are two issues here:

In an earlier posting
(<Qz7sd.87138$7i4.47592@bgtnsc05-news.ops.worldnet.att.net>), you said
that "I think that the call to memcmp evokes undefined behavior"; that
positively shocked me, because I knew that the functions like memcmp
were required to access "characters" and compare using "unsigned char",
and I am (or was) pretty sure that this is something you can do on raw
memory.  (There was never any doubt in my mind, of course, that what
those characters contain if the object is a pointer -- deleted or not
--
is implementation dependent.  And also, that even if for two valid
pointers p and q, p == q, it is implementation defined whether memcmp(
&p, &q, sizeof( p ) ) returns 0 or not.)

I'm still up in the air on this one.  Did you just misread my posting,
or are you contending that accessing the memory that once was a pointer
and is still allocated raw memory is undefined behavior, even if the
access is to the individual bytes (char or unsigned char) of the
object?
This is one thing I always thought you could do on any allocated
memory.  (And I repeat, what I am talking about here is NOT the memory
which has been freed, but the memory which contains the now invalid
pointer itself.)

The other question, of course, is the only one I thought was initially
present: can delete modify the bit pattern of the memory of the pointer
being deleted.  From memory, my impression was that according to the
ARM, it could (but it's been a long time since I read the ARM, my
memory
isn't always that good, and I easily could have misinterpreted
something
anyway).  On the other hand, I cannot find any words in the standard
which would allow it.  Which would mean that if I memcpy'ed the pointer
before deletion, and memcmp'ed it with the copy after, memcmp should
return 0.

> Here's another way to look at it.  Suppose we have a computer that
> allows hardware read-protection down to the word level.  Suppose
> further that I wish to implement C++ so that for every block of
> dynamically allocated memory, there is a hidden data structure that
> records the address of every pointer that points to that memory.

> Now, suppose that when I delete a block of memory, I arrange for my
> implementation to read-protect every pointer that points to that
> memory.  Assigning a new value to the pointer would undo the read
> protection, but until then, every attempt to read the contents of
that
> pointer would result in a memory-protection fault.

> In that case, your call to memcmp would fail because of an attempt to
> access read-protected memory.

> Are you going to tell me that I'm not allowed to implement C++ that
> way?  If not, what part of the standard prohibits it?

First, legal or not, I'd like to get my hands on that implementation,
because I'll bet it would find a lot of hidden bugs, even in my own
code:-).

But I don't think it would be legal:

- The pointers in my example were local variables, so their storage
duration is rigorously defined in    3.7.2; at the time of the call
to
memcmp, the storage for the pointers was alive.

- A pointer is not a class type with a non-trival constructor, so
according to    3.8, its object lifetime coincides with its storage
duration.  (Note that object lifetime doesn't imply a valid value.
An uninitialized POD is alive, but doesn't have a valid value.)

- According to    3.9/10, a pointer is a POD type.

-    3.9 says that "For any complete POD object type T, whether or not
the object holds a valid value of type T, the underlying bytes
making up the object can be copied into an array of char or
unsigned
char."  Now this isn't quite the same thing as memcmp, but if I can
access the bytes to copy them into an char[], is it possible that I
cannot access them to compare them with a char[]?  The intent,
IMHO,
is clear: I can always access raw memory as an array of char or
unsigned char, and I can always access any object, even an object
with an invalid value, as an array of char or unsigned char.  (Note
that at any rate, this invalidates your theoretical machine.)

If this is really a problem, I could, of course, modify the
original
program to copy the invalid pointer into a second buffer using
memcpy, and then use memcmp on the two buffers.

Of course, all of this only addresses the undefined behavior issue.  I
still don't know whether delete is allowed to modify the bits in its
pointer argument:-).

--
James Kanze           GABI Software         http://www.gabi-soft.fr
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


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Wed, 8 Dec 2004 00:23:26 GMT
Raw View
"Alberto Barbati" <AlbertoBarbati@libero.it> wrote in message
news:Twdtd.8079$Zk.177376@twister2.libero.it...

> That wouldn't be a good message either, IMHO. 3.9/2 explicitly states that
> I shall be able to inspect the underlying representation of p "whether or
> not the object [p in this case] holds a valid value".

Fair enough.  So what do you propose to do with those bytes once you have
them?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Wed, 8 Dec 2004 00:23:27 GMT
Raw View
<kanze@gabi-soft.fr> wrote in message
news:1102417046.760257.129570@c13g2000cwb.googlegroups.com...

> I'm still up in the air on this one.  Did you just misread my posting,
> or are you contending that accessing the memory that once was a pointer
> and is still allocated raw memory is undefined behavior, even if the
> access is to the individual bytes (char or unsigned char) of the
> object?
> This is one thing I always thought you could do on any allocated
> memory.  (And I repeat, what I am talking about here is NOT the memory
> which has been freed, but the memory which contains the now invalid
> pointer itself.)

I've changed my mind on this.  You can look at the representation; you just
can't be sure it will mean anything useful.

> The other question, of course, is the only one I thought was initially
> present: can delete modify the bit pattern of the memory of the pointer
> being deleted.  From memory, my impression was that according to the
> ARM, it could (but it's been a long time since I read the ARM, my
> memory
> isn't always that good, and I easily could have misinterpreted
> something
> anyway).  On the other hand, I cannot find any words in the standard
> which would allow it.  Which would mean that if I memcpy'ed the pointer
> before deletion, and memcmp'ed it with the copy after, memcmp should
> return 0.

5.3.5/4: The value of a pointer that refers to deallocated storage is
indeterminate.

That suggests to me that when you deallocate storage, the implementation is
permitted to scribble any pointer that formerly referred to that storage.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Wed, 8 Dec 2004 03:35:02 GMT
Raw View
"Andrew Koenig" wrote:
> "Ben Hutchings" <ben-public-nospam@decadentplace.org.uk> wrote in message
> news:slrncr9fnr.ji2.ben-public-nospam@decadentplace.org.uk...
>
>>> And what do you do if the implementation terminates your program with a
>>> diagnostic message saying "Sorry, you're not allowed to look at that
>>> memory
>>> any more; you've deallocated it."  ?
>>>
>>> That's why I said "assuredly" in my original question.
>>
>> My code looked at p, not *p.  So if my program was terminated I'd file
>> a bug report, since the implementation wouldn't be meeting the
>> requirements in 3.9/2.
>
> I'll respond to your bug report by changing the diagnostic message slightly:
>
>     Sorry, you're not allowed to look at that pointer any more;
>     you invalidated it when you deallocated the memory to which
>     it used to point.

I don't understand.  The paragraph I cited says I can copy the bytes
of a POD object "whether or not the object holds a valid value".  The
values of those bytes are of course unspecified in this case, but that
doesn't appear to result in undefined behaviour.

--
Ben Hutchings
Life would be so much easier if we could look at the source code.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Wed, 8 Dec 2004 03:35:17 GMT
Raw View
<kanze@gabi-soft.fr> wrote in message
news:1102326689.763768.193410@z14g2000cwz.googlegroups.com...
> "Andrew Koenig" wrote:

, evokes undefined behavior.
>
> Which is the crux of the question.  Is accessing the underlying raw
> memory, as an array of unsigned bytes, accessing the value?

I would say it's implementation-defined.  Which means that the
implementation can prohibit it if it pleases.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Wed, 8 Dec 2004 15:00:48 CST
Raw View
"Andrew Koenig" wrote:
> <kanze@gabi-soft.fr> wrote in message
> news:1102417046.760257.129570@c13g2000cwb.googlegroups.com...

> > I'm still up in the air on this one. Did you just misread my
> > posting, or are you contending that accessing the memory that once
> > was a pointer and is still allocated raw memory is undefined
> > behavior, even if the access is to the individual bytes (char or
> > unsigned char) of the object?
> > This is one thing I always thought you could do on any allocated
> > memory. (And I repeat, what I am talking about here is NOT the
> > memory which has been freed, but the memory which contains the now
> > invalid pointer itself.)

> I've changed my mind on this. You can look at the representation; you
> just can't be sure it will mean anything useful.

I agree there.  I never claimed that my example was in any way useful
for anything:-).  We're really quibbling over the number of angels that
can dance on the head of a pin.  But isn't that what comp.std.c++ is
for:-) ?

> > The other question, of course, is the only one I thought was
> > initially present: can delete modify the bit pattern of the memory
> > of the pointer being deleted. From memory, my impression was that
> > according to the ARM, it could (but it's been a long time since I
> > read the ARM, my memory isn't always that good, and I easily could
> > have misinterpreted something anyway). On the other hand, I cannot
> > find any words in the standard which would allow it. Which would
> > mean that if I memcpy'ed the pointer before deletion, and memcmp'ed
> > it with the copy after, memcmp should return 0.

> 5.3.5/4: The value of a pointer that refers to deallocated storage is

> indeterminate.

> That suggests to me that when you deallocate storage, the
> implementation is permitted to scribble any pointer that formerly
> referred to that storage.

In sum, my use of memcmp is perfectly legal, but the results are
totally
unspecified (but it must return a valid int).

Sounds good to me.  I don't know of any implementation that does modify
the value, but none of my code will break if it does.

--
James Kanze           GABI Software         http://www.gabi-soft.fr
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


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Mon, 29 Nov 2004 17:58:50 GMT
Raw View
Kim, Seungtai wrote:
> "Alberto Barbati"
>=20
> #4
>=20
>     char *p =3D 2;
>     char *q(p);
>=20

This is illegal. You can't assign the integer constant 2 to a pointer,=20
so the code above won't even compile.

If you change the first line to

   char *p =3D reinterpret_cast<char*>(2);

then the behaviour is implementation-defined according to =A75.2.10/5.

> #5
>=20
>     char *p =3D new char ;
>     char *clone( p );
>     delete p;
>     f( clone );
>=20

This is undefined behaviour, because making a copy of p before invoking=20
delete does not make any difference. Please notice that "delete p" does=20
*not* change the value stored in p, it simply makes that value (and any=20
copy of it) unusable.

> #6
>=20
>     char *p =3D new char;
>     int i =3D p;
>     delete p;
>     f ( reinterpret_cast<char *> ( i ) );
>=20

I guess you meant "int i =3D reinterpret_cast<int>(p)", because otherwise=
=20
it's illegal, you can't assign a pointer value to an integer variable.

Assuming int is sufficiently large to hold a char* then according to=20
=A75.2.10/5 this example is essentially equivalent to #5, so it's=20
undefined behaviour.

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jdennett@acm.org (James Dennett)
Date: Mon, 29 Nov 2004 17:57:57 GMT
Raw View
Kim, Seungtai wrote:

> "Alberto Barbati"
>
>>>And what about the null-pointer? Isn't it invalid pointer? Is it
>>>special defined non-invalid pointer?
>>
>>Technically speaking the null pointer value is not "invalid". It can be compared and used safely in most contexts except, of
>>course, that dereferencing it produces undefined behaviour. That's different from a "true" invalid pointer value for which *any
>>use* produces undefined behaviour.
>
>
> How about the user-defined value case such like this?
>
> #4
>
>     char *p = 2;

This is an error; there is no implicit conversion from int
to any pointer type.  If you include a reinterpret_cast, then
you have implementation-defined behavior.

>     char *q(p);
>
> Dose it cause the undefined-bahavior, also? And stored
> value case?

The problem is in turning 2 into a pointer value in the first
place.

> #5
>
>     char *p = new char ;
>     char *clone( p );
>     delete p;
>     f( clone );

Undefined, if f takes its argument by value.

>
> And how about converting to integer and reconstructing
> from it case?
>
> #6
>
>     char *p = new char;
>     int i = p;
>     delete p;
>     f ( reinterpret_cast<char *> ( i ) );

Undefined still.

-- James

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Mon, 29 Nov 2004 18:48:13 GMT
Raw View
"Alberto Barbati" <AlbertoBarbati@libero.it> wrote in message
news:cFDqd.56348$Ni.1950485@twister1.libero.it...
Kim, Seungtai wrote:

>Please notice that "delete p" does *not* change the value stored in p,
> it simply makes that value (and any copy of it) unusable.

How would you write a program that would assuredly detect whether "delete p"
changes the value stored in p?  I can't think of a way to do it.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bop@gmb.dk ("Bo Persson")
Date: Mon, 29 Nov 2004 17:59:09 GMT
Raw View
""Kim, Seungtai"" <stkim@yujinrobot.com> skrev i meddelandet
news:cods4d$d9l$1@news.kreonet.re.kr...
> "Alberto Barbati"
>>> And what about the null-pointer? Isn't it invalid pointer? Is it
>>> special defined non-invalid pointer?
>>
>> Technically speaking the null pointer value is not "invalid". It can
>> be compared and used safely in most contexts except, of course, that
>> dereferencing it produces undefined behaviour. That's different from
>> a "true" invalid pointer value for which *any use* produces undefined
>> behaviour.
>
> How about the user-defined value case such like this?
>
> #4
>
>    char *p = 2;
>    char *q(p);

That won't compile, because 2 isn't a valid pointer. Only 0 is special.

>
> Dose it cause the undefined-bahavior, also? And stored
> value case?
>
> #5
>
>    char *p = new char ;
>    char *clone( p );
>    delete p;
>    f( clone );

No, you have deleted the object, making all pointers to it invalid.

>
> And how about converting to integer and reconstructing
> from it case?
>
> #6
>
>    char *p = new char;
>    int i = p;
>    delete p;
>    f ( reinterpret_cast<char *> ( i ) );

No, you have deleted the object, making all pointers to it invalid.  :-)


The problem isn't what you do with the pointer, but what you do with the
object. When you delete an object, ALL pointers to the object becomes
invalid.

On some architectures, the OS might deallocate the memory used by a
deleted object. That would make the address contianed in the pointer
non-existant. Some processors have special address registers or segment
registers that traps on invalid/non-existent addresses.

In order to allow both such configurations, and systems where it would
be expensive to check every pointer access, the C++ standard
specifically states that you don't know what will happen - undefined
behaviour.

Note that popular processors like the x86 can run in segmented mode and
in flat address mode for different programs, even at the same time!


Bo Persson


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Mon, 29 Nov 2004 21:33:25 GMT
Raw View
Andrew Koenig wrote:
> "Alberto Barbati" <AlbertoBarbati@libero.it> wrote in message
> news:cFDqd.56348$Ni.1950485@twister1.libero.it...
> Kim, Seungtai wrote:
>
>
>>Please notice that "delete p" does *not* change the value stored in p,
>>it simply makes that value (and any copy of it) unusable.
>
>
> How would you write a program that would assuredly detect whether "delete p"
> changes the value stored in p?  I can't think of a way to do it.
>

You're right, the potential change of value is not observable behaviour,
so it's nonsense to even talk about it. Thanks for pointing that out.

Fact is that the operand of a delete-expression is not required to be an
l-value. If it is an r-value, it would not be possible to change its
value in any way, so I would find it very surprising to hear about an
implementation that made a special case for l-values in order to perform
an extra (unneeded because unobservable) write-to-memory operation.

Of course, that's just my opinion...

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 30 Nov 2004 03:42:11 GMT
Raw View
Kim, Seungtai wrote:
> How about

It's all bad. There aren't any loopholes. If you
need to play with pointer values, copy them before
deletion into arrays of unsigned char, and then
manipulate those arrays.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: richtesi@informatik.tu-muenchen.de (Simon Richter)
Date: Tue, 30 Nov 2004 15:11:30 GMT
Raw View
Hi,

> Fact is that the operand of a delete-expression is not required to be an
> l-value. If it is an r-value, it would not be possible to change its
> value in any way, so I would find it very surprising to hear about an
> implementation that made a special case for l-values in order to perform
> an extra (unneeded because unobservable) write-to-memory operation.

An implementation is allowed to add an extra level of indirection, which
would allow it to invalidate pointers after return from operator delete.

    Simon (wondering if that could be useful for debugging)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Tue, 30 Nov 2004 18:25:46 GMT
Raw View
"Alberto Barbati" <AlbertoBarbati@libero.it> wrote in message
news:VxMqd.58224$Es2.1262559@twister2.libero.it...

> Fact is that the operand of a delete-expression is not required to be an
> l-value. If it is an r-value, it would not be possible to change its value
> in any way, so I would find it very surprising to hear about an
> implementation that made a special case for l-values in order to perform
> an extra (unneeded because unobservable) write-to-memory operation.

I've heard compiler implementors advocate doing exactly that for debugging
purposes.
I don't know whether anyone actually does it.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: iapetus@austin.rr.com (iapetus)
Date: Tue, 30 Nov 2004 18:25:47 GMT
Raw View
> Dose bellow the program have the well-defined behavior?
>
> If so, what is the result at the point of A?
>
>     T *p = new T;
>     T *clone = p;
>
>     delete p;
>
>     clone ==  p; // A

I think everyone's been quite clear that this (and all its variants)
are undefined and clearly bad.

So the question is, why on earth would you *want* to do something
like this (somehow use a pointer to an object you just deleted)?

-- Mickey Moore

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: stkim@yujinrobot.com ("Kim, Seungtai")
Date: Wed, 1 Dec 2004 20:19:24 GMT
Raw View
"iapetus"
>> Dose bellow the program have the well-defined behavior?
>>
>> If so, what is the result at the point of A?
>>
>>     T *p = new T;
>>     T *clone = p;
>>
>>     delete p;
>>
>>     clone ==  p; // A
>
> I think everyone's been quite clear that this (and all its variants)
> are undefined and clearly bad.
>
> So the question is, why on earth would you *want* to do something
> like this (somehow use a pointer to an object you just deleted)?

My original doubt comes from implementating a algorithm. In this algorithm
if my original assumption is correct(of course, it's not),
it can be implemented more conveniently. Yes, there is another way to
implement it with comforming programming. But it requires double coding.

The algorithm is (partially present) :

    ... If the node is left one, delete the node and connect the left line
    to deleted one's child. Else if the node is right one,
    delete the node and connect right line to deleted one's child,
    directly....

I've got the point in the problem as many others present here. But, I still
wonder why the Standard make deleted pointer's value unusable.
In this point, I'm not clear .What kinds the assumption is made for
the invalid value in the Abstract Machine? All the jobs with this value make
only undefined-behaviour?

Thanks in advices for all.

--
S Kim <stkim@yujinrobot.com>


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Wed, 1 Dec 2004 20:23:56 GMT
Raw View
ark@acm.org ("Andrew Koenig") wrote in message
news:<OuJqd.72125$7i4.16037@bgtnsc05-news.ops.worldnet.att.net>...
> "Alberto Barbati" <AlbertoBarbati@libero.it> wrote in message
> news:cFDqd.56348$Ni.1950485@twister1.libero.it...
> Kim, Seungtai wrote:

> >Please notice that "delete p" does *not* change the value stored in
> >p, it simply makes that value (and any copy of it) unusable.

> How would you write a program that would assuredly detect whether
> "delete p" changes the value stored in p?  I can't think of a way to
> do it.

    unsigned char buf[ sizeof( char* ) ] ;
    char* p = new char ;
    memcpy( buf, &p, sizeof( char* ) ) ;
    delete p ;
    std::cout << memcmp( buf, &p, sizeof( char* ) ) << std::endl ;

First, I think you'll agree that that there is no undefined behavior in
the above.  But is the value output to cout guaranteed to be 0, or not?

(Not that I really care -- it won't make any difference in any code I
write:-).)

--
James Kanze           GABI Software         http://www.gabi-soft.fr
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

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Wed, 1 Dec 2004 20:22:19 GMT
Raw View
"Andrew Koenig" wrote:
> "Alberto Barbati" <AlbertoBarbati@libero.it> wrote in message
> news:cFDqd.56348$Ni.1950485@twister1.libero.it...
> Kim, Seungtai wrote:
>
>>Please notice that "delete p" does *not* change the value stored in p,
>> it simply makes that value (and any copy of it) unusable.
>
> How would you write a program that would assuredly detect whether "delete p"
> changes the value stored in p?  I can't think of a way to do it.

You can certainly check whether the bytes of its object representation
have changed, which I think is probably what Alberto Barbati meant.

#include <cstring>
#include <iostream>

int main()
{
    char * p = new char;
    char pb[sizeof(char *)];
    std::memcpy(pb, (char *)&p, sizeof(char *));
    delete p;
    std::cout << (std::memcmp(pb, (char *)&p, sizeof(char *))
                  ? "changed" : "unchanged")
              << std::endl;
}

--
Ben Hutchings
When in doubt, use brute force. - Ken Thompson

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Michiel.Salters@logicacmg.com (Michiel Salters)
Date: Thu, 2 Dec 2004 05:35:04 GMT
Raw View
iapetus@austin.rr.com (iapetus) wrote in message news:<MPG.1c15b06fcfa244b99896c2@news-server.austin.rr.com>...
> > Dose bellow the program have the well-defined behavior?
> >
> >     T *p = new T;
> >     T *clone = p;
> >
> >     delete p;
> >
> >     clone ==  p; // A
>
> I think everyone's been quite clear that this (and all its variants)
> are undefined and clearly bad.
>
> So the question is, why on earth would you *want* to do something
> like this (somehow use a pointer to an object you just deleted)?

The most common case is removing a key from a container. If you
remove the key first, you could lose the value to delete. If you
delete the pointer first, the container will contain that invalid
value.

E.g. removing an int* from std::set<int*> when these int*s are
owning pointers.

HTH,
Michiel Salters

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nagle@animats.com (John Nagle)
Date: Thu, 2 Dec 2004 05:38:00 GMT
Raw View
Kim, Seungtai wrote:

> "iapetus"
>
>>>Dose bellow the program have the well-defined behavior?

    This is a theological debate between the "that's bad code and
shouldn't be expected to work" and the "if it's at all possible
to give meaningful semantics to bad code, it should work"
factions.

    We go through this occasionally, and it's worth realizing
when we're doing so.

    Semantics of bad code, code that shouldn't work but
usually does, is an ongoing problem.  Classic examples
include accessing data after a delete (which worked in
some early implementations), assignment to "this"
(once allowed, now forbidden), "delete this" (still
allowed, but questionable), null references (not
allowed, but sometimes used), casting function pointers
to "void*" (formally undefined, but works on most platforms),
and continuing past failed "assert" statements in non-debug mode
(allowed, but highly questionable).

     C++ has rather a lot of this sort of thing.  Perhaps too much.

    John Nagle
    Animats

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ron@sensor.com (Ron Natalie)
Date: Thu, 2 Dec 2004 18:22:11 GMT
Raw View
Michiel Salters wrote:

> The most common case is removing a key from a container. If you
> remove the key first, you could lose the value to delete. If you
> delete the pointer first, the container will contain that invalid
> value.
>
> E.g. removing an int* from std::set<int*> when these int*s are
> owning pointers.
>
Huh?  Just assign it to a temporary value, delete it from the
set, and the delete the object.   In the case of set, you probably
already have it in a variable.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: mgmoore@austin.rr.com (Mickey Moore)
Date: Thu, 2 Dec 2004 19:33:03 GMT
Raw View
> The most common case is removing a key from a container. If you
> remove the key first, you could lose the value to delete. If you
> delete the pointer first, the container will contain that invalid
> value.
>
> E.g. removing an int* from std::set<int*> when these int*s are
> owning pointers.

Perhaps I'm overlooking something here, but can't you just obtain a
copy of the int* from the set, remove the element, then delete
through the copy?

(And if you were using shared_ptr, you'd just remove it, knowing
deletion would be handled automatically, correct?)

-- Mickey Moore

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: richtesi@informatik.tu-muenchen.de (Simon Richter)
Date: Thu, 2 Dec 2004 18:21:23 GMT
Raw View
Hi,

> The most common case is removing a key from a container. If you
> remove the key first, you could lose the value to delete. If you
> delete the pointer first, the container will contain that invalid
> value.

> E.g. removing an int* from std::set<int*> when these int*s are
> owning pointers.

That violates the "one pointer/capability - one object" principle,
besides being a non-issue because the pointer value can be copied to a
temporary location, the item removed from the set (which will not call
delete on the pointer) and the pointee destroyed afterwards. If that is
not possible, perhaps because the object holding the pointer is not
copiable, then you have much greater problems than the use of a deleted
pointer.

    Simon

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: oldwolf@inspire.net.nz (Old Wolf)
Date: Fri, 3 Dec 2004 05:18:51 GMT
Raw View
iapetus@austin.rr.com (iapetus) wrote:
> >     T *p = new T;
> >     T *clone = p;
> >
> >     delete p;
> >
> >     clone ==  p; // A
>
> I think everyone's been quite clear that this (and all its variants)
> are undefined and clearly bad.
>
> So the question is, why on earth would you *want* to do something
> like this (somehow use a pointer to an object you just deleted)?

I don't know, but you could ask Maxis. One of the Microsoft
OS developers reported that they had to make a custom memory
allocator that ran when it detected someone was playing Sim City,
because that game would free memory and then continue to use it
for a while (which worked for MS-DOS's memory allocator, or something).

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Sat, 4 Dec 2004 06:14:46 GMT
Raw View
"Ben Hutchings" <ben-public-nospam@decadentplace.org.uk> wrote in message
news:slrncqs11f.5st.ben-public-nospam@decadentplace.org.uk...
> "Andrew Koenig" wrote:
>> "Alberto Barbati" <AlbertoBarbati@libero.it> wrote in message
>> news:cFDqd.56348$Ni.1950485@twister1.libero.it...
>> Kim, Seungtai wrote:
>>
>>>Please notice that "delete p" does *not* change the value stored in p,
>>> it simply makes that value (and any copy of it) unusable.
>>
>> How would you write a program that would assuredly detect whether "delete
>> p"
>> changes the value stored in p?  I can't think of a way to do it.
>
> You can certainly check whether the bytes of its object representation
> have changed, which I think is probably what Alberto Barbati meant.

And what do you do if the implementation terminates your program with a
diagnostic message saying "Sorry, you're not allowed to look at that memory
any more; you've deallocated it."  ?

That's why I said "assuredly" in my original question.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Sat, 4 Dec 2004 21:38:37 GMT
Raw View
kanze@gabi-soft.fr wrote in message news:<d6652001.0412010821.461147e7@posting.google.com>...
kanze@gabi-soft.fr wrote:
> ark@acm.org ("Andrew Koenig") wrote in message
> news:<OuJqd.72125$7i4.16037@bgtnsc05-news.ops.worldnet.att.net>...
>> "Alberto Barbati" <AlbertoBarbati@libero.it> wrote in message news:cFDqd.56348$Ni.1950485@twister1.libero.it...
>> Kim, Seungtai wrote:
>>> Please notice that "delete p" does *not* change the value stored
in
>>> p, it simply makes that value (and any copy of it) unusable.
>> How would you write a program that would assuredly detect whether
>> "delete p" changes the value stored in p?  I can't think of a way
to
>> do it.
>     unsigned char buf[ sizeof( char* ) ] ;
>     char* p = new char ;
>     memcpy( buf, &p, sizeof( char* ) ) ;
>     delete p ;
>     std::cout << memcmp( buf, &p, sizeof( char* ) ) << std::endl ;
>
> First, I think you'll agree that that there is no undefined behavior in
> the above.  But is the value output to cout guaranteed to be 0, or not?

Note: what you're doing doesn't tell us whether the value of 'p'
changed; it can only tell us whether the representation of 'p'
changed. There's a mapping between representation and value, and that
mapping can change as the result of the execution of a delete
expression. I don't believe that 'delete p' is allowed to change the
representation, but I'm sure it can change the value.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Sat, 4 Dec 2004 21:38:56 GMT
Raw View
Andrew Koenig wrote:
> "Ben Hutchings" <ben-public-nospam@decadentplace.org.uk> wrote in message
> news:slrncqs11f.5st.ben-public-nospam@decadentplace.org.uk...
>
>>"Andrew Koenig" wrote:
>>
>>>"Alberto Barbati" <AlbertoBarbati@libero.it> wrote in message
>>>news:cFDqd.56348$Ni.1950485@twister1.libero.it...
>>>Kim, Seungtai wrote:
>>>
>>>
>>>>Please notice that "delete p" does *not* change the value stored in p,
>>>>it simply makes that value (and any copy of it) unusable.
>>>
>>>How would you write a program that would assuredly detect whether "delete
>>>p"
>>>changes the value stored in p?  I can't think of a way to do it.
>>
>>You can certainly check whether the bytes of its object representation
>>have changed, which I think is probably what Alberto Barbati meant.
>
> And what do you do if the implementation terminates your program with a
> diagnostic message saying "Sorry, you're not allowed to look at that memory
> any more; you've deallocated it."  ?

Ben Hutchings was referring to the memory representation of the pointer
itself, not to the memory to which the pointer "points". The former is
not going to be deallocated by a delete expression, only the latter is.

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pal_ari@yahoo.co.in (Arijit)
Date: Sat, 4 Dec 2004 22:57:45 GMT
Raw View
Andrew Koenig wrote:

> And what do you do if the implementation terminates your program with a
> diagnostic message saying "Sorry, you're not allowed to look at that memory
> any more; you've deallocated it."  ?
>
> That's why I said "assuredly" in my original question.

Does the following work ?

int main()
{
   int *p = new int;
   cout << p << endl;
   delete p;

   for(int i=0;i< sizeof(int*);++i)
     cout << *(reinterpret_cast<char*>(&p)+i);
}

It doesn't use the value of p after its deleted directly.

Or if I use memcpy on (char*)(&p) to copy the contents of p. I don't use
value of p. Will it work ?

-Arijit

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Sun, 5 Dec 2004 00:47:17 GMT
Raw View
ark@acm.org ("Andrew Koenig") wrote in message news:<fz7sd.87135$7i4.8843@bgtnsc05-news.ops.worldnet.att.net>...
> "Ben Hutchings" <ben-public-nospam@decadentplace.org.uk> wrote in message
> news:slrncqs11f.5st.ben-public-nospam@decadentplace.org.uk...
> > "Andrew Koenig" wrote:
> >> "Alberto Barbati" <AlbertoBarbati@libero.it> wrote in message
> >> news:cFDqd.56348$Ni.1950485@twister1.libero.it...
> >> Kim, Seungtai wrote:
> >>
> >>>Please notice that "delete p" does *not* change the value stored in p,
> >>> it simply makes that value (and any copy of it) unusable.
> >>
> >> How would you write a program that would assuredly detect whether "delete
> >> p"
> >> changes the value stored in p?  I can't think of a way to do it.
> >
> > You can certainly check whether the bytes of its object representation
> > have changed, which I think is probably what Alberto Barbati meant.
>
> And what do you do if the implementation terminates your program with a
> diagnostic message saying "Sorry, you're not allowed to look at that memory
> any more; you've deallocated it."  ?

I'd report a bug in the compiler to the vendor. The memory containing
the representation of 'p' is not deallocated by 'delete p', unless p
happens to stored inside the same memory allocation that p points at.
That's certainly possible, but it's not true in general.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Sun, 5 Dec 2004 00:47:28 GMT
Raw View
James Kuyper wrote:
> I don't believe that 'delete p' is allowed to change the
> representation

Why not?

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Sat, 27 Nov 2004 18:51:44 GMT
Raw View
Kim, Seungtai wrote:
> I'm confusing at the basic point.
>=20
> Dose bellow the program have the well-defined behavior?
>=20
> If so, what is the result at the point of A?
>=20
>     T *p =3D new T;
>     T *clone =3D p;
>=20
>     delete p;
>=20
>     clone =3D=3D  p; // A
>=20
> I think it has the well-defined. And I think the if-statement's
> condition yeilds the value true. Because the value of pointer
> itself is never touched. So, at the point of A, the clone and
> p might have a same value.

No, the code has undefined behaviour.

> But, the Standard say at 5.3.5/p4
>=20
>     The cast-expression in a delete-expression shall be evaluated exact=
ly=20
> once.
>     If the delete-expression calls the implementation deallocation func=
tion=20
> (3.7.3.2),
>     and if the operand of the delete expression is not the null pointer=
=20
> constant,
>     the deallocation function will deallocate the storage referenced
>     by the pointer thus rendering the pointer invalid.
>=20
>     [Note: the value of a pointer that refers to deallocated storage is=
=20
> indeterminate.]
>=20
> See the note. It seems to be that it say that all kinds of pointer's va=
lues
> are to be invalid after delete-operation. But, I cannot find the any ex=
act
> described section about it in the Standard. Where is it infered?
> And what is the exact SC's indent about that the usage of the deleted
> pointer? Never use it? Or some kinds of operations are restrictly allow=
ed?

In =A73.7.3.2/4 is said:

"[...] The effect of using an invalid pointer value (including passing=20
it to a deallocation function) is undefined."

with the footnote: "On some implementations, it causes a=20
system-generated runtime fault."

Therefore, any *use* of the value of an invalid pointer, including=20
comparing it with anything is undefined behaviour. A variable holding=20
such a value cannot be *read* but can be written to, for example:

   delete p;
   p =3D 0; // ok!

And that's practically the only thing you can do with p.

Hope it helps,

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Sat, 27 Nov 2004 18:51:44 GMT
Raw View
"Kim, Seungtai" wrote:
> I'm confusing at the basic point.
>
> Dose bellow the program have the well-defined behavior?

No.

> If so, what is the result at the point of A?
>
>     T *p = new T;
>     T *clone = p;
>
>     delete p;
>
>     clone ==  p; // A
>
> I think it has the well-defined. And I think the if-statement's
> condition yeilds the value true. Because the value of pointer
> itself is never touched.

In practice this tends to be true, but this is not guaranteed.

<snip>
> But, the Standard say at 5.3.5/p4
<snip>
>     [Note: the value of a pointer that refers to deallocated storage is
> indeterminate.]
>
> See the note. It seems to be that it say that all kinds of pointer's values
> are to be invalid after delete-operation. But, I cannot find the any exact
> described section about it in the Standard. Where is it infered?

It is stated in 3.7.3.2/4.

> And what is the exact SC's indent about that the usage of the deleted
> pointer? Never use it? Or some kinds of operations are restrictly allowed?

You must not use its value in any way.  You may of course assign a new
value to it.

--
Ben Hutchings
Q.  Which is the greater problem in the world today, ignorance or apathy?
A.  I don't know and I couldn't care less.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Michiel.Salters@logicacmg.com (Michiel Salters)
Date: Sat, 27 Nov 2004 23:52:36 GMT
Raw View
stkim@yujinrobot.com ("Kim, Seungtai") wrote in message news:<co26s9$3l6$1@news.kreonet.re.kr>...
> I'm confusing at the basic point.
>
> Dose bellow the program have the well-defined behavior?
>
> If so, what is the result at the point of A?
>
>     T *p = new T;
>     T *clone = p;
>
>     delete p;
>
>     clone ==  p; // A

> I think it has the well-defined. And I think the if-statement's
> condition yeilds the value true. Because the value of pointer
> itself is never touched. So, at the point of A, the clone and
> p might have a same value.

Wrong. The only valid use of a pointer object, after the pointer
value has been deleted, is to be reinitialised with a new value.
You don't write to p; instead you read a value from p. That causes
undefined behavior.

This might happen because the pointer no longer points to allocated
memory. This in turn may be a reason for the OS to reshuffle it's
memory management structures, which in trun may cause the CPU to
detect the illegal pointer. The comparison is especially tricky,
as that is likely a comparison between two address registers. A
CPU that checks the values of address registers would trap there.

> But, the Standard say at 5.3.5/p4
>
>     The cast-expression in a delete-expression shall be evaluated exactly
>     once.If the delete-expression calls the implementation deallocation
>     function (3.7.3.2), and if the operand of the delete expression is
>     not the null pointer constant, the deallocation function will
>     deallocate the storage referenced by the pointer thus rendering the
>     pointer invalid.
>
>     [Note: the value of a pointer that refers to deallocated storage is
>      indeterminate.]
>
> See the note. It seems to be that it say that all kinds of pointer's values
> are to be invalid after delete-operation. But, I cannot find the any exact
> described section about it in the Standard. Where is it infered?
> And what is the exact SC's indent about that the usage of the deleted
> pointer? Never use it? Or some kinds of operations are restrictly allowed?

See 3.7.3.2/4
.. the deallocation function shall deallocate the storage referenced by
the pointer, rendering invalid all pointers referring to any part of the
deallocated storage. The effect of using an invalid pointer value
(including passing it to a deallocation function) is undefined.

HTH,
Michiel Salters

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: stkim@yujinrobot.com ("Kim, Seungtai")
Date: Sun, 28 Nov 2004 22:22:42 GMT
Raw View
"Alberto Barbati"
> In    3.7.3.2/4 is said:
>
> "[...] The effect of using an invalid pointer value (including passing it
> to a deallocation function) is undefined."
>
> with the footnote: "On some implementations, it causes a system-generated
> runtime fault."
>
> Therefore, any *use* of the value of an invalid pointer, including
> comparing it with anything is undefined behaviour.

If so, what is the invalid pointer value? The Standard dose not define
exactly the terminology. Just it say case by case,

3.7.3.2/p4

    ...the deallocation function shall deallocate the storage referenced
    by the pointer, rendering invalid all pointers referring to any part
    of the deallocated storage. The effect of using an invalid
    pointer value...

18.4.1.2/p9

    The deallocation function (3.7.3.2) called by the array form of
    a delete-expression to render the value of ptr invalid.

..

And how about bellow programs? They make also undefine-behavior?

#1

    char *p;
    char *q(p);

#2

    char *p = new char;
    delete p;
    p = new char;

#3

    void f ( char *p ) ;

    ...
    char *p;
    f(p);

And what about the null-pointer? Isn't it invalid pointer? Is it
special defined non-invalid pointer?

Thanks in advices.

--
S Kim <stkim@yujinrobot.com>


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Sun, 28 Nov 2004 23:29:59 GMT
Raw View
Kim, Seungtai wrote:
> "Alberto Barbati"
>
>>Therefore, any *use* of the value of an invalid pointer, including
>>comparing it with anything is undefined behaviour.
>
> If so, what is the invalid pointer value? The Standard dose not define
> exactly the terminology.

What's the point in knowing the value of an invalid pointer? Any use of
it produces an undefined behaviour!

> And how about bellow programs? They make also undefine-behavior?
>
> #1
>
>     char *p;
>     char *q(p);

Undefined behaviour. p is left uninitialized, so potentially p holds an
invalid pointer. The second line attempt to copy (therefore "use") the
potentially invalid pointer and so it's undefined behaviour.

> #2
>
>     char *p = new char;
>     delete p;
>     p = new char;

This is correct. After the delete, p contains an invalid pointer, but
writing to p does *not* constitute a "use" of the value of p.

> #3
>
>     void f ( char *p ) ;
>
>     ...
>     char *p;
>     f(p);

Undefined behaviour. Again p is uninitialized and passing it as a
parameter to f() constitutes a "use" of its value.

> And what about the null-pointer? Isn't it invalid pointer? Is it
> special defined non-invalid pointer?

Technically speaking the null pointer value is not "invalid". It can be
compared and used safely in most contexts except, of course, that
dereferencing it produces undefined behaviour. That's different from a
"true" invalid pointer value for which *any use* produces undefined
behaviour.

HTH,

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: stkim@yujinrobot.com ("Kim, Seungtai")
Date: Mon, 29 Nov 2004 04:25:49 GMT
Raw View
"Alberto Barbati"
>> And what about the null-pointer? Isn't it invalid pointer? Is it
>> special defined non-invalid pointer?
>
> Technically speaking the null pointer value is not "invalid". It can be compared and used safely in most contexts except, of
> course, that dereferencing it produces undefined behaviour. That's different from a "true" invalid pointer value for which *any
> use* produces undefined behaviour.

How about the user-defined value case such like this?

#4

    char *p = 2;
    char *q(p);

Dose it cause the undefined-bahavior, also? And stored
value case?

#5

    char *p = new char ;
    char *clone( p );
    delete p;
    f( clone );

And how about converting to integer and reconstructing
from it case?

#6

    char *p = new char;
    int i = p;
    delete p;
    f ( reinterpret_cast<char *> ( i ) );

Thanks in advice.

--
S Kim <stkim@yujinrobot.com>


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org ("Andrew Koenig")
Date: Mon, 29 Nov 2004 17:58:41 GMT
Raw View
""Kim, Seungtai"" <stkim@yujinrobot.com> wrote in message
news:cods4d$d9l$1@news.kreonet.re.kr...
> How about the user-defined value case such like this?

> #4
>
>    char *p = 2;
>    char *q(p);

This example should not compile, because the only integer value that can be
converted to a pointer is a constant zero.

> #5
>
>    char *p = new char ;
>    char *clone( p );
>    delete p;
>    f( clone );

Undefined.  Deleting p renders any copies of p invalid, so passing clone as
a function argument is undefined behavior.

> And how about converting to integer and reconstructing
> from it case?
>
> #6
>
>    char *p = new char;
>    int i = p;
>    delete p;
>    f ( reinterpret_cast<char *> ( i ) );
>
> Thanks in advice.

All uses of reinterpret_cast are implementation-defined.  If, however, you
expect reinterpret_cast<char*>(i) to yield the same value that p had
earlier, then passing that value to f is undefined.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: stkim@yujinrobot.com ("Kim, Seungtai")
Date: Mon, 29 Nov 2004 17:58:15 GMT
Raw View
"Kim, Seungtai"
>
> #4
>
>    char *p = 2;
>    char *q(p);


    char *p = reinterpret_cast<char *>( 2 );
    char *q( p );

--
S Kim <stkim@yujinrobot.com>


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: stkim@yujinrobot.com ("Kim, Seungtai")
Date: Mon, 29 Nov 2004 17:58:23 GMT
Raw View
"Kim, Seungtai"
>
> #6
>
>    char *p = new char;
>    int i = p;
>    delete p;
>    f ( reinterpret_cast<char *> ( i ) );

    char *p = new char;
    int i = reinterpret_cast<int >( p );
    delete p;
    f ( reinterpret_cast<char *> ( i ) );

--
S Kim <stkim@yujinrobot.com>


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: stkim@yujinrobot.com ("Kim, Seungtai")
Date: Wed, 24 Nov 2004 16:38:08 GMT
Raw View
I'm confusing at the basic point.

Dose bellow the program have the well-defined behavior?

If so, what is the result at the point of A?

    T *p = new T;
    T *clone = p;

    delete p;

    clone ==  p; // A

I think it has the well-defined. And I think the if-statement's
condition yeilds the value true. Because the value of pointer
itself is never touched. So, at the point of A, the clone and
p might have a same value.

But, the Standard say at 5.3.5/p4

    The cast-expression in a delete-expression shall be evaluated exactly
once.
    If the delete-expression calls the implementation deallocation function
(3.7.3.2),
    and if the operand of the delete expression is not the null pointer
constant,
    the deallocation function will deallocate the storage referenced
    by the pointer thus rendering the pointer invalid.

    [Note: the value of a pointer that refers to deallocated storage is
indeterminate.]

See the note. It seems to be that it say that all kinds of pointer's values
are to be invalid after delete-operation. But, I cannot find the any exact
described section about it in the Standard. Where is it infered?
And what is the exact SC's indent about that the usage of the deleted
pointer? Never use it? Or some kinds of operations are restrictly allowed?

Confusing. Clear me.

Thanks in advices.

--
S Kim <stkim@yujinrobot.com>


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]