Re: Does this constitute a memory leak?
Nikola wrote:
Hmm, I think I've found where my test example differs from the actual
program. Here's the fixed test program, now with examples:
#include <stdio.h>
#include <string.h>
class tst {
public:
char *a;
tst() {
printf("Default constructor.\n");
a = new char[1];
a[0] = 0;
}
tst(const char *b) {
printf("Construct from char * %s.\n", b);
a = new char[strlen(b) + 1];
strcpy(a, b);
}
tst(const tst ©) {
printf("Copy constructor for %s.\n", copy.a);
a = new char[strlen(copy.a) + 1];
strcpy(a, copy.a);
}
You will want to add an assignment operator:
tst & operator= ( tst lhs ) {
std::swap( a, lhs.a );
return ( *this );
}
~tst() {
printf("Destructor for %s.\n", this->a);
delete [] a;
}
};
tst &func3() {
printf("FUNC3\n");
tst *a = new tst("3456");
return *a; // <---- THIS (Copy constructor is called)
}
You might consider returning by value:
tst func4 ( void ) {
return ( tst( "3456" ) );
}
int main(void) {
tst a = func3(); // this is how I called - copy constructor is called
tst &b = func3(); // Kai-Uwe called this - no copy constructor calls
tst c = ""; // the way it's done in my program
c = func3(); // no copy constructor is called
Here, you _use_ the assignment operator. I am positive that the compiler
generated one is _not_ what you want.
delete (&b);
// How do I free c?
Freeing c is not the problem (the destructor will do that). The problem lies
in the the pointer allocated by func3 from whose pointee c is initialized.
return 0;
}
This is the output:
FUNC3
Construct from char * 3456.
Copy constructor for 3456.
FUNC3
Construct from char * 3456.
Construct from char * .
FUNC3
Construct from char * 3456.
Destructor for 3456.
Destructor for 3456.
Destructor for 3456.
I suppose the way I do it is rather bad because first memory is taken
for tst c = ""; (it's member a, to be more precise) and it's never freed
and then it's modified to point to another string, thus forever losing
the pointer to what was previously allocated.
That problem will be solved by an assignment operator. In that case
tst c = "";
c = tst( "3456" );
would be fine and the destructors of all temporaries involved will get rid
of all memory allocated along the way.
In any case, I think I'm in for some modifications.
The typical C++ way is to return by value.
Best
Kai-Uwe Bux