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 >
C/C++ Source or Header  |  1996-04-09  |  3KB  |  108 lines

  1. //
  2. // BUG0796.CPP
  3. //
  4. // This program demonstrates a problem that
  5. // shows up in Visual C++ 4.0 and earlier.
  6. // When VC++ generates a default assignment
  7. // operator for class B, it performs a binary
  8. // copy of exactly one byte.  Unfortunately,
  9. // it hasn't allocated space for that one byte
  10. // in the base class, so it inadvertently
  11. // writes over a single byte in its only
  12. // data member before calling the data
  13. // member's assignment operator.  In this
  14. // program, the result is that the buffer
  15. // member has been mangled, resulting in
  16. // a copy to an invalid destination.
  17. //
  18.  
  19. #include <iostream.h>
  20. #include <iomanip.h>
  21. #include <string.h>
  22.  
  23. class buffer {
  24.     public :
  25.         char *p;
  26.         buffer( char *name ) {
  27.             p = new char[ 257 ];
  28.             cout << "in ctor p = "
  29.                  << hex
  30.                  << (void *) p
  31.                  << ", name = "
  32.                  << name
  33.                  << "\n";
  34.             strcpy( p, name );
  35.         }
  36.         buffer &operator=( const buffer &that )
  37.         {
  38.             cout << "buffer::operator=( that ) "
  39.                  << "that.p  = "
  40.                  << hex
  41.                  << (void *) that.p
  42.                  << ", "
  43.                  << that.p
  44.                  << endl;
  45.             cout << "                          "
  46.                  << "this->p = "
  47.                  << hex
  48.                  << (void *) p
  49.                  << ", "
  50.                  << p
  51.                  << endl;
  52.             strcpy( p, that.p );
  53.             return *this;
  54.         }
  55.         ~buffer() { delete[] p; }
  56. };
  57.  
  58. class A {
  59. };
  60.  
  61. class B : public A {
  62.     public :
  63.         B( char *name ) : b( name ){}
  64.         buffer b;
  65. };
  66.  
  67. main()
  68. {
  69.  
  70.     cout << "Even though A has no data members, it\n"
  71.          << "still has to occupy a minimum of one\n"
  72.          << "byte according to the C++ standard.\n"
  73.          << "Class B has a single pointer, so under a\n"
  74.          << "32 bit programming model, it should be\n"
  75.          << "exactly four bytes larger.\n"
  76.          << "Unfortunately, VC++ forgets to add that\n"
  77.          << "extra byte from the base class:\n\n";
  78.  
  79.     cout << "sizeof( A ) = " << dec << sizeof( A )
  80.          << "  "
  81.          << "sizeof( B ) = " << dec << sizeof( B )
  82.          << "\n\n";
  83.  
  84.     cout << "As the two constructors are called, note\n"
  85.          << "the addresses of the two memory buffers\n"
  86.          << "that have been allocated for the names\n"
  87.          << "of the objects:\n\n";
  88.  
  89.     B b1( "object b1" );
  90.     B b2( "object b2" );
  91.  
  92.     cout << "\nWhen the assignment operator is\n"
  93.          << "invoked, the buffer values for this and\n"
  94.          << "that should match what you see printed\n"
  95.          << "out from the constructors:\n\n";
  96.     char *mark = b2.b.p;
  97.     b2 = b1;
  98.     if ( mark == b2.b.p )
  99.         cout << "\nNo bug detected!\n"
  100.              << "Expect a safe exit.\n"
  101.              << endl;
  102.     else
  103.         cout << "\nSince the pointer has been mangled,\n"
  104.              << "expect a GPF upon exit!\n"
  105.              << endl;
  106.     return 1;
  107. }
  108.