473,503 Members | 2,004 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

dereferencing memory location some time after deleting the same one

Hi

what do you think of the following? Why are we permitted to do that?
And why the C++ Library doesn't stop someone willing to perfom that
assignement (*a = 20)?
#include <iostream>

using std::cout;

int main()
{
int *a = new int(10);
cout << *a << " " << a << '\n';
delete a;
*a = 20;
cout << *a << " " << a << '\n';
}
After compiling (with gcc-3.4.1 on Linux and with VC++ on XP as well):

#./a.out
10 0x9f6d008
20 0x9f6d008
Maybe what is worse is that if you compile and run the above written
code without the line "*a = 20;" you get the following output:

#./a.out
10 0x9f6d008
0 0x9f6d008

I didn't know that yhis is the behaviour until I read a post on
it.comp.lang.c++ from someone who didn't understand why He got the
printed list of all the nodes of a bin-tree with a "0" output at the
position of some previously deleted nodes. So He didn't realize that
He forgot to assign NULL to the parent pointer field addressing the
just deleted nodes (and unfortunatelly all the deleted nodes were leaf
ones).

I think that if He had got a crash, dereferencing a pointer to
deallocated memory, He would had understood what was bad with his
cancelling algorithm.

So wouldn't it be better if a program crashed when someone tried to
dereference a pointer to deleted memory location?

Ciao,

Fabio De Francesco
Jul 22 '05 #1
10 1871
fabio de francesco wrote:
what do you think of the following? Why are we permitted to do that?
Why not? The Standard says that any program that attempts to dereference
a pointer after the pointer has been deleted, has undefined behaviour.
An attempt to define what should happen in such case is a waste of time.
And why the C++ Library doesn't stop someone willing to perfom that
assignement (*a = 20)?
How would it "stop" you?


#include <iostream>

using std::cout;

int main()
{
int *a = new int(10);
cout << *a << " " << a << '\n';
delete a;
*a = 20;
cout << *a << " " << a << '\n';
}
After compiling (with gcc-3.4.1 on Linux and with VC++ on XP as well):

#./a.out
10 0x9f6d008
20 0x9f6d008
Undefined behaviour. Anything is allowed to happen.


Maybe what is worse is that if you compile and run the above written
code without the line "*a = 20;" you get the following output:

#./a.out
10 0x9f6d008
0 0x9f6d008
Again, it really shows nothing. The behaviour of that code is
not defined. It is allowed to produce _any_ output or no output
whatsoever.

I didn't know that yhis is the behaviour until I read a post on
it.comp.lang.c++ from someone who didn't understand why He got the
printed list of all the nodes of a bin-tree with a "0" output at the
position of some previously deleted nodes. So He didn't realize that
He forgot to assign NULL to the parent pointer field addressing the
just deleted nodes (and unfortunatelly all the deleted nodes were leaf
ones).
OK

I think that if He had got a crash, dereferencing a pointer to
deallocated memory, He would had understood what was bad with his
cancelling algorithm.
He could get a crash. Or he could get a thank-you note in the mail.
Or he could get his hard drive formatted. Anything is allowed to
happen.

So wouldn't it be better if a program crashed when someone tried to
dereference a pointer to deleted memory location?


No, it wouldn't. Forcing the program to crash would require some
special processing. Besides, requiring the program to crash would
only permit creation of C++ programs for systems where "crash" is
defined. What if the system _cannot_ (or must not) crash? Even
debugging such system would be a problem.

V
Jul 22 '05 #2
fabio de francesco wrote:
Hi

what do you think of the following? Why are we permitted to do that?
What makes you think you are?
And why the C++ Library doesn't stop someone willing to perfom that
assignement (*a = 20)?
Because the behavior is undefined, which means the program is not required
to crash.
#include <iostream>

using std::cout;

int main()
{
int *a = new int(10);
cout << *a << " " << a << '\n';
delete a;
*a = 20;
cout << *a << " " << a << '\n';
}
After compiling (with gcc-3.4.1 on Linux and with VC++ on XP as well):

#./a.out
10 0x9f6d008
20 0x9f6d008
Maybe what is worse is that if you compile and run the above written
code without the line "*a = 20;" you get the following output:

#./a.out
10 0x9f6d008
0 0x9f6d008

I didn't know that yhis is the behaviour until I read a post on
it.comp.lang.c++ from someone who didn't understand why He got the
printed list of all the nodes of a bin-tree with a "0" output at the
position of some previously deleted nodes. So He didn't realize that
He forgot to assign NULL to the parent pointer field addressing the
just deleted nodes (and unfortunatelly all the deleted nodes were leaf
ones).

I think that if He had got a crash, dereferencing a pointer to
deallocated memory, He would had understood what was bad with his
cancelling algorithm.

So wouldn't it be better if a program crashed when someone tried to
dereference a pointer to deleted memory location?


It's not so easy to determine every illegal memory access without explicit
hardware support.

Jul 22 '05 #3
> So wouldn't it be better if a program crashed when someone tried to
dereference a pointer to deleted memory location?


Better is a matter of opinion. It would definitely be easier to debug
but what if the trade off was that the program takes 10 times as long
to run.

While you can't get the compiler to enforce it, you can get close to what
you want by adaptint the style of always NULLing a pointer after deleting it:

delete x;
x = 0;

samuel
Jul 22 '05 #4
Victor Bazarov <v.********@comAcast.net> wrote in message news:<Ls****************@newsread1.dllstx09.us.to. verio.net>...
fabio de francesco wrote:
what do you think of the following? Why are we permitted to do that?
Why not? The Standard says that any program that attempts to dereference
a pointer after the pointer has been deleted, has undefined behaviour.
An attempt to define what should happen in such case is a waste of time.


I am sorry for my English because sometimes I am not able to explain
what the it is the exact point of my question: I already know that the
behaviour is undefined as the Standard says. What I intended to ask is
why the Standard say that. I think that Standard would be better not
to allow dereferencing a pointer to deleted memory for the reasons I
wrote.
And why the C++ Library doesn't stop someone willing to perfom that
assignement (*a = 20)?
How would it "stop" you?


Ok, let me try a way. I don't have enough IT competence to suggest the
best solution but I start from knowing that the Library takes pages of
memory from the kernel VM and manages the allocation of little pieces
of that to programs requiring bits of that memory. Is it true, isn't
it? So the responsibility for finer allocation of memory is in charge
of the Library that eventually could mark deleted locations as
unavailable and recollect them. May be this is not the right way but I
just tried to answer your question.


#include <iostream>

using std::cout;

int main()
{
int *a = new int(10);
cout << *a << " " << a << '\n';
delete a;
*a = 20;
cout << *a << " " << a << '\n';
}
After compiling (with gcc-3.4.1 on Linux and with VC++ on XP as well):

#./a.out
10 0x9f6d008
20 0x9f6d008


Undefined behaviour. Anything is allowed to happen.


Maybe what is worse is that if you compile and run the above written
code without the line "*a = 20;" you get the following output:

#./a.out
10 0x9f6d008
0 0x9f6d008


Again, it really shows nothing. The behaviour of that code is
not defined. It is allowed to produce _any_ output or no output
whatsoever.


That has been said before.

I didn't know that this is the behaviour until I read a post on
it.comp.lang.c++ from someone who didn't understand why He got the
printed list of all the nodes of a bin-tree with a "0" output at the
position of some previously deleted nodes. So He didn't realize that
He forgot to assign NULL to the parent pointer field addressing the
just deleted nodes (and unfortunatelly all the deleted nodes were leaf
ones).
OK

I think that if He had got a crash, dereferencing a pointer to
deallocated memory, He would had understood what was bad with his
cancelling algorithm.


He could get a crash. Or he could get a thank-you note in the mail.
Or he could get his hard drive formatted. Anything is allowed to
happen.


I think it shouldn't be allowed to happen anything not specified, for
the sake of safety.

So wouldn't it be better if a program crashed when someone tried to
dereference a pointer to deleted memory location?


No, it wouldn't. Forcing the program to crash would require some
special processing. Besides, requiring the program to crash would
only permit creation of C++ programs for systems where "crash" is
defined. What if the system _cannot_ (or must not) crash? Even
debugging such system would be a problem.


I don't know. What does the standard defines when a program tries to
access a memory location allocated to another process?
V


Thank you,

Fabio De Francesco
Jul 22 '05 #5
Rolf Magnus <ra******@t-online.de> wrote in message news:<cl*************@news.t-online.com>...
fabio de francesco wrote:
Hi

what do you think of the following? Why are we permitted to do that?
SNIP
And why the C++ Library doesn't stop someone willing to perfom that
assignement (*a = 20)?
I think that if He had got a crash, dereferencing a pointer to
deallocated memory, He would had understood what was bad with his
cancelling algorithm.

So wouldn't it be better if a program crashed when someone tried to
dereference a pointer to deleted memory location?


It's not so easy to determine every illegal memory access without explicit
hardware support.


As I wrote to Victor Bazarov, if the deleted memory is still in the
hands of the C++ Library, the Library itself could deny access some
way. Whereas if the memory has been given back to the kernel we don't
have to worry about it because the kernel (Linux at least) will emit a
segmentation fault. I don't think any hardware support is needed, but
I can be wrong.

Thank you,

Fabio De Francesco
Jul 22 '05 #6
"fabio de francesco" <fm**@tiscali.it> wrote...
Victor Bazarov <v.********@comAcast.net> wrote in message
news:<Ls****************@newsread1.dllstx09.us.to. verio.net>...
fabio de francesco wrote:
> what do you think of the following? Why are we permitted to do that?
Why not? The Standard says that any program that attempts to dereference
a pointer after the pointer has been deleted, has undefined behaviour.
An attempt to define what should happen in such case is a waste of time.


I am sorry for my English because sometimes I am not able to explain
what the it is the exact point of my question: I already know that the
behaviour is undefined as the Standard says. What I intended to ask is
why the Standard say that.


You have to ask in comp.std.c++ then. This newsgroup (comp.lang.c++)
discusses _how_ the things are, not _why_. comp.std.c++ discusses
_why_ things are the way they are.
I think that Standard would be better not
to allow dereferencing a pointer to deleted memory for the reasons I
wrote.


It can't disallow it. Just like it can't disallow dividing by 0 or
calculating the arcsine of 5. Maybe that's what you want to do, who
is the Standard Committee to prevent you from doing that? Freedom
is something that is very important. You're free to do what you want.
The compiler and the code is free to behave as it sees fit.
> And why the C++ Library doesn't stop someone willing to perfom that
> assignement (*a = 20)?


How would it "stop" you?


Ok, let me try a way. I don't have enough IT competence to suggest the
best solution but I start from knowing that the Library takes pages of
memory from the kernel VM and manages the allocation of little pieces
of that to programs requiring bits of that memory. Is it true, isn't
it? So the responsibility for finer allocation of memory is in charge
of the Library that eventually could mark deleted locations as
unavailable and recollect them. May be this is not the right way but I
just tried to answer your question.


Yes, and you have fallen into something platform-specific, like 'VM' or
'kernel' or 'pages of memory'. All this is beyond the scope of the
language standard. The main reason is that as soon as the language tries
to incorporate anything OS-specific in the prescribed behaviour, it cannot
be implemented on a system where something is different. It becomes
OS-dependent. That is not acceptable for C++.
> I didn't know that this is the behaviour until I read a post on
> it.comp.lang.c++ from someone who didn't understand why He got the
> printed list of all the nodes of a bin-tree with a "0" output at the
> position of some previously deleted nodes. So He didn't realize that
> He forgot to assign NULL to the parent pointer field addressing the
> just deleted nodes (and unfortunatelly all the deleted nodes were leaf
> ones).


OK
>
> I think that if He had got a crash, dereferencing a pointer to
> deallocated memory, He would had understood what was bad with his
> cancelling algorithm.


He could get a crash. Or he could get a thank-you note in the mail.
Or he could get his hard drive formatted. Anything is allowed to
happen.


I think it shouldn't be allowed to happen anything not specified, for
the sake of safety.


Safety is NOT a concern of a language. It's a concern of a programmer
and/or a library implementer. If you think it's not safe, DO NOT DO IT.
> So wouldn't it be better if a program crashed when someone tried to
> dereference a pointer to deleted memory location?


No, it wouldn't. Forcing the program to crash would require some
special processing. Besides, requiring the program to crash would
only permit creation of C++ programs for systems where "crash" is
defined. What if the system _cannot_ (or must not) crash? Even
debugging such system would be a problem.


I don't know. What does the standard defines when a program tries to
access a memory location allocated to another process?


There is no such thing as "another process" in the Standard. The C++
language program model is a single process running sequential operations
on a single processor.

If you want security, hand-holding, garbage collection, electric fences
or anything of this sort, C++ is not your language. There are other
languages that have them. Slower, bulkier, but safer, less demanding
on the programmer.

Victor
Jul 22 '05 #7
>>hardware support.


As I wrote to Victor Bazarov, if the deleted memory is still in the
hands of the C++ Library, the Library itself could deny access some
way. Whereas if the memory has been given back to the kernel we don't
have to worry about it because the kernel (Linux at least) will emit a
segmentation fault. I don't think any hardware support is needed, but
I can be wrong.

You are. IF the memory is in hands of the C++ library, HOW can it
trap any access to it ? The kernel gives segfault based on help from
hardware, but memory deleted are not usually given back to the kernel.
Jul 22 '05 #8
fabio de francesco wrote:


As I wrote to Victor Bazarov, if the deleted memory is still in the
hands of the C++ Library, the Library itself could deny access some
way.
So how should it do that?
The only way would be to intercept each and every access to memory and
look in its internal tables if a request to that specific access is granted.
Well. Programs spend roughly 90% of their time in accessing memory. But this
also would mean that most of the programs time would be spent by checking
if a memory access is granted or not. Besides: The checking routine itself
needs to access memory, who is going to monitor that routine?

Whereas if the memory has been given back to the kernel we don't
have to worry about it because the kernel (Linux at least) will emit a
segmentation fault. I don't think any hardware support is needed, but
I can be wrong.


It strictly isn't needed, the compiler could insert a call to the checking
function whenever code is emitted to access a memory location. But as said:
Your program wouldn't do much more then spending an overwhelming amount
of time in that check function.

Consider this analogy:
There is a library. If you lend a book someone is checking if you are
allowed to lend that book. So far so fine. But now we change the rules slightly:
Instead of checking once for the whole book, the libraraian is now required to
check for each page if you are allowed to read that page. Or better: For each line,
each word, each character. This way the librarian can be very sure that you don't see
anything you shouldn't see. But the bacjdraft is: You could no longer actually 'read'
the book, since you would spend most of your time in asking the librarian if
you are allowed to read the next character, word, line.

It is like in everyday life: 100% safety is possible, but it is impractical. Und thus
it is never done. You can stealth a computer against hackers or viruses or spam or whatever.
You just neeed to remove any and all input devices to that computer, then there would
be no way that a virus could infect it. Hmm. But how are you going to actually work with
that computer in this case?

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #9

"fabio de francesco" <fm**@tiscali.it> wrote in message
news:ba*************************@posting.google.co m...
Hi

what do you think of the following? Why are we permitted to do that?
And why the C++ Library doesn't stop someone willing to perfom that
assignement (*a = 20)?
#include <iostream>

using std::cout;

int main()
{
int *a = new int(10);
cout << *a << " " << a << '\n';
delete a;
*a = 20;
cout << *a << " " << a << '\n';
}
After compiling (with gcc-3.4.1 on Linux and with VC++ on XP as well):

#./a.out
10 0x9f6d008
20 0x9f6d008
Maybe what is worse is that if you compile and run the above written
code without the line "*a = 20;" you get the following output:

#./a.out
10 0x9f6d008
0 0x9f6d008

I didn't know that yhis is the behaviour until I read a post on
it.comp.lang.c++ from someone who didn't understand why He got the
printed list of all the nodes of a bin-tree with a "0" output at the
position of some previously deleted nodes. So He didn't realize that
He forgot to assign NULL to the parent pointer field addressing the
just deleted nodes (and unfortunatelly all the deleted nodes were leaf
ones).

I think that if He had got a crash, dereferencing a pointer to
deallocated memory, He would had understood what was bad with his
cancelling algorithm.

So wouldn't it be better if a program crashed when someone tried to
dereference a pointer to deleted memory location?

Ciao,

Fabio De Francesco


I know that some standard libraries implement additional checks at run time,
when allocating or freeing the memory. However, they are implemented only
for debug code, using assertions.

As others already said, C++ is not a safe programming language, but it is
efficient in terms of performance. By providing additional, mandatory checks
for safety, a lot of performance may be lost. This can be compensated by a
good discipline in programming.

Catalin
Jul 22 '05 #10
fabio de francesco wrote:
Rolf Magnus <ra******@t-online.de> wrote in message
news:<cl*************@news.t-online.com>...
fabio de francesco wrote:
> Hi
>
> what do you think of the following? Why are we permitted to do that?
SNIP
> And why the C++ Library doesn't stop someone willing to perfom that
> assignement (*a = 20)?
> I think that if He had got a crash, dereferencing a pointer to
> deallocated memory, He would had understood what was bad with his
> cancelling algorithm.
>
> So wouldn't it be better if a program crashed when someone tried to
> dereference a pointer to deleted memory location?
It's not so easy to determine every illegal memory access without
explicit hardware support.


As I wrote to Victor Bazarov, if the deleted memory is still in the
hands of the C++ Library, the Library itself could deny access some
way.


What exactly do you mean by "some way"? It's right that the library has
probably some way to determine whether a particular memory location is
properly allocated, but how would it detect which memory location a program
tries to access? After all, it accesses the memory directly, not through
library functions.
Whereas if the memory has been given back to the kernel we don't
have to worry about it because the kernel (Linux at least) will emit a
segmentation fault. I don't think any hardware support is needed, but
I can be wrong.


Even the kernel facility you describe does use hardware support. The memory
is ogranized in pages. If a program tries to access an address in its
virtual address space that doesn't map to a part of a page of physical
memory, the CPU generates an interrupt and the kernel gets control over the
CPU.

Jul 22 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
14677
by: Scott | last post by:
I'm new to ASP, but I've been programming in VB for several years, and I'm having a few issues with this ASP enhancement I'm working on. I've found ASP to be a lot different than what I'm use to...
11
2821
by: William Buch | last post by:
I have a strange problem. The code isn't written by me, but uses the qsort function in stdlib. ALWAYS, the fourth time through, the memory location of variable list (i.e. mem location = 41813698)...
10
2755
by: s.subbarayan | last post by:
Dear all, I happen to come across this exciting inspiring article regarding memory leaks in this website: http://www.embedded.com/story/OEG20020222S0026 In this article the author mentions:...
16
2310
by: Michael Maes | last post by:
Hi, How would I handle Dereferencing in vb.Net 2003. Something like: Dim txt As TextBox = DirectCast("txt" & someStringVariable, TextBox) This sadly won't work because a type of string...
62
17619
by: ivan.leben | last post by:
How can I really delete a preloaded image from memory/disk cache? Let's say I preload an image by creating an Image object and setting its src attribute to desired URL: var img = new Image();...
4
1677
by: rn5a | last post by:
Is it possible to practically see the memory location stored in a variable? For e.g. consider the statement Dim myInt As Integer = 10 If I am not wrong, the memory location allocated to...
20
3179
by: prashant.khade1623 | last post by:
I am not getting the exact idea. Can you please explain me with an example. Thanks
0
1389
by: michael ngong | last post by:
pramod@rtimes.com (Pramod Ramachandran) wrote in message news:<6616e304.0306240122.4dd3ecd5@posting.google.com>... Permit me start with the second question. It would be easier to be more...
50
3435
by: arunajob | last post by:
Hi all, If I have a piece of code something like this void main(void) { char * p1="abcdefghijklmn"; ............................................. }
0
7091
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7282
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7342
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
5586
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5018
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4680
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3171
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3162
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
391
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.