| Title: | C++ | 
| Notice: | Read 1.* and use keywords (e.g. SHOW KEY/FULL KIT_CXX_VAX_VMS) | 
| Moderator: | DECCXX::AMARTIN | 
| Created: | Fri Nov 06 1987 | 
| Last Modified: | Thu Jun 05 1997 | 
| Last Successful Update: | Fri Jun 06 1997 | 
| Number of topics: | 3604 | 
| Total number of notes: | 18242 | 
    A customer submitted the following test case.  He feels that the
    results are incorrect.  He expects the output string to be:
    
    		String S2 String S3
    
    instead he gets:
    
    		String S3 String S3
    
    The debugger shows that new  was returning the same address in both
    calls to the non-default constructor.
    
    Is this expected behavior?
    
    Thanks,
    
    Elin
    
#include <iostream.h>
#include <string.h>
class SimpleString {
                    public:
                    int count;
                    char *buffer;
                    SimpleString();
                    SimpleString(char *);
                    ~SimpleString();
                   };
SimpleString::SimpleString ()
{
    count = 0;
    buffer = 0;
}
SimpleString::SimpleString (char * str)
{
    count = strlen(str) + 1;
    buffer = new char [count];
    strcpy(buffer,str);
}
SimpleString::~SimpleString ()
{
    delete [] buffer;
}
int main ()
{
    SimpleString S1;
    SimpleString S2 = "String S2";
    SimpleString S3("String S3");
    SimpleString *pS1 = new SimpleString;
    SimpleString *pS2 = new SimpleString("Pointer pS2");
    SimpleString *pS3 = new SimpleString [2];
    cout << S2.buffer << S3.buffer << endl;
    return 0;
}
    
| T.R | Title | User | Personal Name | Date | Lines | 
|---|---|---|---|---|---|
| 3443.1 | SPECXN::DERAMO | Dan D'Eramo | Mon Feb 10 1997 18:11 | 53 | |
| >    Is this expected behavior?
        
        For a broken program, yes. :-)
        
        He needs a copy constructor for his class,
        
        	SimpleString(const SimpleString &);
        
        with definition something like
        
        	SimpleString::SimpleString(const SimpleString &rhs)
        	{
        	    // don't use this to copy construct an object with itself!
        	    if (rhs.count > 0) {
        	        count = rhs.count;
        	        buffer = new char[count];
        	        memcpy(buffer, rhs.buffer, count);
        	    } else {
        	        count = 0;
        	        buffer = 0;
        	    }
        	}
        
        He also needs a similar assignment operator, but just the copy
        constructor here would fix the small example.
        
>    The debugger shows that new  was returning the same address in both
>    calls to the non-default constructor.
        
>    SimpleString S1;
>    SimpleString S2 = "String S2";
>    SimpleString S3("String S3");
        S1 is constructed with SimpleString::SimpleString() and
        S3 is constructed with SimpleString::SimpleString(char *).
        The customer thinks S2 is also being constructed with
        SimpleString::SimpleString(char *) but he is wrong.  A
        temporary object is being constructed with
        SimpleString::SimpleString(char *) and S2 is being constructed
        with the compiler-synthesized copy constructor using that
        temporary.  Then the temporary is destroyed.  So the sequence
        of new char [] / delete char [] operations is
        
        	temporary.buffer = new char[10];
        	S2.buffer = temporary.buffer;
        	delete [] temporary.buffer;
        	// S2.buffer is now a dangling pointer
        	S3.buffer = new char[10]; // returns same pointer as S2.buffer
        
        That's why the class needs its own copy constructor and
        assignment operator.
        
        Dan
 | |||||
| 3443.2 | Thanks!! | CSC32::E_VAETH | Suffering from temporary brain cramp, stay tuned | Tue Feb 11 1997 09:43 | 0 |