Bad Reference?

Y

Yogesh

Hi all,
Please look at the code below:

int main (int argc, char * const argv[])
{
int * i = (int *)malloc(sizeof(int));
*i = 50;
int &badref = *i;
printf("%d\n",badref);
delete i;
printf("%d\n",badref);
//This reference is bad coz "i" is deleted
badref = 70;
printf("%d\n",badref);
return 0 ;
}

I compiled and ran this program on gcc 4.0 and it worked.
it prints:
50
50
70

In the above case I would call the reference "badref" a bad reference
because
it is alias to var that is deleted.
My question is:
Do we check if the reference is bad, before using it?
If so, how?

Regards,
Yogesh Kini
 
R

Rolf Magnus

Yogesh said:
Hi all,
Please look at the code below:

int main (int argc, char * const argv[])
{
int * i = (int *)malloc(sizeof(int));
*i = 50;
int &badref = *i;
printf("%d\n",badref);
delete i;
printf("%d\n",badref);
//This reference is bad coz "i" is deleted

Yes. Using it invokes undefined behavior.
badref = 70;
printf("%d\n",badref);
return 0 ;
}

I compiled and ran this program on gcc 4.0 and it worked.

That's one possible result of undefined behavior.
it prints:
50
50
70

In the above case I would call the reference "badref" a bad reference
because it is alias to var that is deleted.

That's right.
My question is:
Do we check if the reference is bad, before using it?
If so, how?

There is no way.
 
D

Daniel T.

"Yogesh said:
Hi all,
Please look at the code below:

int main (int argc, char * const argv[])
{
int * i = (int *)malloc(sizeof(int));
*i = 50;
int &badref = *i;
printf("%d\n",badref);
delete i;
printf("%d\n",badref);
//This reference is bad coz "i" is deleted
badref = 70;
printf("%d\n",badref);
return 0 ;
}

I compiled and ran this program on gcc 4.0 and it worked.
it prints:
50
50
70

In the above case I would call the reference "badref" a bad reference
because
it is alias to var that is deleted.
My question is:
Do we check if the reference is bad, before using it?
If so, how?

You can't check if the reference is bad. You also can't check if a
pointer is bad (ie after the delete, there is no way to determine that
dereferencing 'i' is undefined.)

That's just the way it is in c++.
 
A

Audison.Athena

I think C++ don't do this complex check.
becaue the lifetime of an object is a runtime property of the object,
so I think it's too complex to implement such check in compile-time
check. and C++ compiler doesn't generate some extra code to enable
run-time for such thing.
refer to ISO C++ 14882 chapter 3.8 the seventh item:
if after the lifetime of an object has ended and before the storage
which the object occupied is reused or released, a new object is
created at the storage location which the original object occupied, a
pointer that pointed to the original object, a reference that referred
to the original object, or the name of original object will
automatically refer to the new object and, once the lifetime of the new
object has started, can be used to manipulate the new object...
if between the delete expression and the assignment expression there's
another new expression that actually the same location which is
occupied by the original object then the assignment expression is
really right.
so it's impossible to do this check during compile-time and it's
improper to do this check in run-time due to too much burden on
run-time efficiency(think there's always any some other code around the
delete expression just for this check), so I guess c++ implementation
just let it pass.
 
A

A. W. Dunstan

Yogesh said:
Hi all,
Please look at the code below:

int main (int argc, char * const argv[])
{
int * i = (int *)malloc(sizeof(int));
*i = 50;
int &badref = *i;
printf("%d\n",badref);
delete i;
printf("%d\n",badref);
//This reference is bad coz "i" is deleted
badref = 70;
printf("%d\n",badref);
return 0 ;
}

It's not C++, but tools like valgrind can catch many of these errors. For
example:

g++ -Wall badref.cpp -g -o badref
valgrind badref

==11523== Memcheck, a memory error detector for x86-linux.
==11523== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==11523== Using valgrind-2.4.0, a program supervision framework for
x86-linux.
==11523== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==11523== For more details, rerun with: -v
==11523==
50
==11523== Mismatched free() / delete / delete []
==11523== at 0x1B9098CF: operator delete(void*) (vg_replace_malloc.c:155)
==11523== by 0x8048513: main (badref.cpp:10)
==11523== Address 0x1B92F028 is 0 bytes inside a block of size 4 alloc'd
==11523== at 0x1B909222: malloc (vg_replace_malloc.c:130)
==11523== by 0x80484DD: main (badref.cpp:6)
==11523==
==11523== Invalid read of size 4
==11523== at 0x804851A: main (badref.cpp:11)
==11523== Address 0x1B92F028 is 0 bytes inside a block of size 4 free'd
==11523== at 0x1B9098CF: operator delete(void*) (vg_replace_malloc.c:155)
==11523== by 0x8048513: main (badref.cpp:10)
50
==11523==
==11523== Invalid write of size 4
==11523== at 0x8048530: main (badref.cpp:13)
==11523== Address 0x1B92F028 is 0 bytes inside a block of size 4 free'd
==11523== at 0x1B9098CF: operator delete(void*) (vg_replace_malloc.c:155)
==11523== by 0x8048513: main (badref.cpp:10)
==11523==
==11523== Invalid read of size 4
==11523== at 0x8048539: main (badref.cpp:14)
==11523== Address 0x1B92F028 is 0 bytes inside a block of size 4 free'd
==11523== at 0x1B9098CF: operator delete(void*) (vg_replace_malloc.c:155)
==11523== by 0x8048513: main (badref.cpp:10)
70
==11523==
==11523== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 16 from 1)
==11523== malloc/free: in use at exit: 0 bytes in 0 blocks.
==11523== malloc/free: 1 allocs, 1 frees, 4 bytes allocated.
==11523== For counts of detected errors, rerun with: -v
==11523== No malloc'd blocks -- no leaks are possible.

Such tools can't catch everything (like casting a pointer as a pointer to an
unrelated type), but they're better than nothing.
 
H

Howard

Yogesh said:
Hi all,
Please look at the code below:

int main (int argc, char * const argv[])
{
int * i = (int *)malloc(sizeof(int));
*i = 50;
int &badref = *i;
printf("%d\n",badref);
delete i;

In addition to the comments others have made, I'd point out that if you used
"malloc", you need to use "free" to free the memory. You use "delete" when
you allocate the memory with "new", not "malloc".

-Howard
 
R

red floyd

Yogesh said:
Hi all,
Please look at the code below:

int main (int argc, char * const argv[])
{
int * i = (int *)malloc(sizeof(int));
*i = 50;
int &badref = *i;
printf("%d\n",badref);

your undefined behavior starts at this line:
delete i;
delete-ing a pointer not allocated with new. Your initialization
of i should be: int* i = new int;
Then this delete would be valid.

printf("%d\n",badref);
//This reference is bad coz "i" is deleted
Correct. You have undefined behavior (of course everything *after*
delete is undefined, the way the code is written).
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top