| 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 |