My Answer
First, let me explain the differences among the functions shown in the hints as on the last page:
- For FunctionName(ValueType para), any value will be copied at first, and the copy is the real object accessed in the function. The original value would never be changed. The copy will be removed after the function ends.
- For FunctionName(ValueType *para), the pointer will be copied at first. The copy pointer will be accessed in the function. The original value might be changed via the copy pointer. The copy pointer will be removed after the function ends, but the referred value won't be removed. For something like FunctionName(ValueType para), only the COPY will be removed.
- For FunctionName(ValueType ¶), no copying is done. The original object will be accessed directly in the function.
Now, let me go through the quiz code.
In main(), constructor A() is called; the pchTest member value of the Atest object is "Just Test!". Then, the Atest object is copied as clsAtest by the default copy constructor whenever the show() function is being called. The default constructor will copy only the value without allocating any memory automatically. That is, it will, by default, copy the value of Atest.pchTest to clsAtest.pchTest. Now, clsAtest.pchTest and Atest.pchTest point to the same memory. Then, the process displays "Just Test!" and clsAtest is removed at the end of show(), of course. So, the ~A() destructor is called.
Do you see the problem? The clsAtest.pchTest is deleted, and so is the memory that clsAtest.pchTest points to; that is also referred to by Atest.pchTest, but Atest is still alive! Now, Atest.pchTest actually points to an invalid memory! When the process exits main(), Atest will be deleted; the memory refered by Atest.pchTest will be deleted again. A memory error has occurred.
I think you might have some solutions now. Here, I share my three solutions; two are temporary solutions and one is a permanent cure.
Temporary solution 1: Use a pointer
void show(A *clsAtest)
{
printf("%s",clsAtest->GetContent());
}
void main()
{
A Atest("Just Test!");
show(&Atest);
return 0;
}
A pointer that refers to the Atest object will be copied; call it pAtest. Then, pAtest is accessed in show(). pAtest will be removed later, but the memory referred to by pAtest won't be deleted. Atest.pchTest still keeps the valid memory.
Temporary solution 2: Use a reference
void show(A &clsAtest)
{
printf("%s",clsAtest.GetContent());
}
void main()
{
A Atest("Just Test!");
show(Atest);
return 0;
}
This solution neither copies before entering the functions nor removes when the function ends. The process accesses the Atest object itself in the functions. If you don't want to modify any member value, use const, as shown below:
void show(const A & clsAtest)
Permanent cure
First, add a copy constructor:
A::A(const A &SourceA)
{
pchTest = new char[strlen(SourceA.pchTest)+1];
strcpy(pchTest,SourceA.pchTest);
}
When the process copies Atest, a copy constructor will be called so that cpA has its own pointer (cpA.pchTest), and its own memory referred to by cpA.pchTest. When the process exits show(), it deletes the memory that belongs to cpA, but not to Atest. No matter which kind of function has been called, no system error would occurr.
The same resource management issues will also occur in an assignment; for example:
void main()
{
A Atest("Just Test!");
A Atest2("Test Again!");
Atest = Atest2;
show(Atest);
return 0;
}
Thus, you need to override the assignment operator:
A& A::operator= (const A &SourceA)
{
if( this != &SourceA )
{
delete [] pchText;
pchText = new char[strlen(SourceA.pchText)+1];
strcpy(pchText,SourceA.pchText);
}
return *this;
}
The entire permanent cure code is on the next page.
Comments
There are no comments yet. Be the first to comment!