home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 31
/
CDASC_31_1996_juillet_aout.iso
/
vrac
/
wdj0796.zip
/
NELSON.ZIP
/
BUG0796.CPP
next >
Wrap
C/C++ Source or Header
|
1996-04-09
|
3KB
|
108 lines
//
// BUG0796.CPP
//
// This program demonstrates a problem that
// shows up in Visual C++ 4.0 and earlier.
// When VC++ generates a default assignment
// operator for class B, it performs a binary
// copy of exactly one byte. Unfortunately,
// it hasn't allocated space for that one byte
// in the base class, so it inadvertently
// writes over a single byte in its only
// data member before calling the data
// member's assignment operator. In this
// program, the result is that the buffer
// member has been mangled, resulting in
// a copy to an invalid destination.
//
#include <iostream.h>
#include <iomanip.h>
#include <string.h>
class buffer {
public :
char *p;
buffer( char *name ) {
p = new char[ 257 ];
cout << "in ctor p = "
<< hex
<< (void *) p
<< ", name = "
<< name
<< "\n";
strcpy( p, name );
}
buffer &operator=( const buffer &that )
{
cout << "buffer::operator=( that ) "
<< "that.p = "
<< hex
<< (void *) that.p
<< ", "
<< that.p
<< endl;
cout << " "
<< "this->p = "
<< hex
<< (void *) p
<< ", "
<< p
<< endl;
strcpy( p, that.p );
return *this;
}
~buffer() { delete[] p; }
};
class A {
};
class B : public A {
public :
B( char *name ) : b( name ){}
buffer b;
};
main()
{
cout << "Even though A has no data members, it\n"
<< "still has to occupy a minimum of one\n"
<< "byte according to the C++ standard.\n"
<< "Class B has a single pointer, so under a\n"
<< "32 bit programming model, it should be\n"
<< "exactly four bytes larger.\n"
<< "Unfortunately, VC++ forgets to add that\n"
<< "extra byte from the base class:\n\n";
cout << "sizeof( A ) = " << dec << sizeof( A )
<< " "
<< "sizeof( B ) = " << dec << sizeof( B )
<< "\n\n";
cout << "As the two constructors are called, note\n"
<< "the addresses of the two memory buffers\n"
<< "that have been allocated for the names\n"
<< "of the objects:\n\n";
B b1( "object b1" );
B b2( "object b2" );
cout << "\nWhen the assignment operator is\n"
<< "invoked, the buffer values for this and\n"
<< "that should match what you see printed\n"
<< "out from the constructors:\n\n";
char *mark = b2.b.p;
b2 = b1;
if ( mark == b2.b.p )
cout << "\nNo bug detected!\n"
<< "Expect a safe exit.\n"
<< endl;
else
cout << "\nSince the pointer has been mangled,\n"
<< "expect a GPF upon exit!\n"
<< endl;
return 1;
}