J
JKop
I have some code which when compiled on my system prints:
<output>
AnyClass Constructor for: blah
AnyClass Copy Constructor for: Copy of blah
AnyClass Copy Constructor for: Copy of Copy of blah
AnyClass Constructor for: monkey
AnyClass Assignment Operator: monkey = Copy of blah
AnyClass Assignment Operator: blah = Copy of Copy of blah
AnyClass Assignment Operator: Copy of blah = ¦.C
AnyClass Copy Constructor for: Copy of ¦.C
AnyClass Constructor for: cheese
blah
Copy of blah
monkey
Copy of ¦.C
cheese
AnyClass Destructor for: cheese
AnyClass Destructor for: Copy of ¦.C
AnyClass Destructor for: monkey
AnyClass Destructor for: Copy of Copy of blah
AnyClass Destructor for: Copy of blah
AnyClass Destructor for: blah
</output>
Note the line where it says "Copy of ¦.C". . . there's something corrupted
there. I've looked through my code a few times but can't spot who what when
where or why. Here's the code. I've highlighted with asterisks the line
which results in the corruption.
Here goes:
#include <iostream>
#include <cstddef>
#include <cstring>
class AnyClass
{
public:
static unsigned const &object_counter;
//The above is a const reference to simulate a read-only variable
unsigned to_play_with;
const char* GetName() const
{
return name;
}
private:
static unsigned object_counter_prv;
//The above is the actual non-const variable
char* name;
public:
AnyClass(const char* const in_name, unsigned const in_to_play_with = 0)
: to_play_with(in_to_play_with)
{
std::size_t length = std::strlen( in_name );
name = new char[length += 1];
memcpy(name, in_name, length);
++object_counter_prv;
std::cout << "\n AnyClass Constructor for: " << name << '\n';
}
AnyClass(AnyClass const &original) : to_play_with
(original.to_play_with)
{
std::size_t length = std::strlen( original.name );
name = new char[length += 9]; //9 = 8 + 1 (1 for the null
character)
memcpy( name, "Copy of " , 8 ); // . . .waste of a null
character
memcpy( &name[8], original.name, length -= 9 ); //Take the 9
back off
name[length += 8] = '\0';
++object_counter_prv;
std::cout << "\nAnyClass Copy Constructor for: " << name << '\n';
}
AnyClass& operator=(AnyClass const &other)
{
//NB: There is no name change whatsoever
to_play_with = other.to_play_with;
std::cout << "\n AnyClass Assignment Operator: " << name <<
" = " << other.name << '\n';
}
~AnyClass()
{
std::cout << "\n AnyClass Destructor for: " << name << '\n';
delete [] name;
--object_counter_prv;
}
};
unsigned AnyClass:bject_counter_prv = 0;
unsigned const &AnyClass:bject_counter = AnyClass:bject_counter_prv;
int main()
{
AnyClass blah("blah");
AnyClass poo = blah;
AnyClass toke = poo;
AnyClass monkey("monkey");
monkey = poo;
AnyClass cow(poo = blah = toke); // **** CORRUPTION ***
AnyClass cheese = AnyClass("cheese");
std::cout << blah.GetName() << '\n';
std::cout << poo.GetName() << '\n';
std::cout << monkey.GetName() << '\n';
std::cout << cow.GetName() << '\n'; // *** shows corruption again ***
std::cout << cheese.GetName() << '\n';
}
Can anyone spot the error?
-JKop
<output>
AnyClass Constructor for: blah
AnyClass Copy Constructor for: Copy of blah
AnyClass Copy Constructor for: Copy of Copy of blah
AnyClass Constructor for: monkey
AnyClass Assignment Operator: monkey = Copy of blah
AnyClass Assignment Operator: blah = Copy of Copy of blah
AnyClass Assignment Operator: Copy of blah = ¦.C
AnyClass Copy Constructor for: Copy of ¦.C
AnyClass Constructor for: cheese
blah
Copy of blah
monkey
Copy of ¦.C
cheese
AnyClass Destructor for: cheese
AnyClass Destructor for: Copy of ¦.C
AnyClass Destructor for: monkey
AnyClass Destructor for: Copy of Copy of blah
AnyClass Destructor for: Copy of blah
AnyClass Destructor for: blah
</output>
Note the line where it says "Copy of ¦.C". . . there's something corrupted
there. I've looked through my code a few times but can't spot who what when
where or why. Here's the code. I've highlighted with asterisks the line
which results in the corruption.
Here goes:
#include <iostream>
#include <cstddef>
#include <cstring>
class AnyClass
{
public:
static unsigned const &object_counter;
//The above is a const reference to simulate a read-only variable
unsigned to_play_with;
const char* GetName() const
{
return name;
}
private:
static unsigned object_counter_prv;
//The above is the actual non-const variable
char* name;
public:
AnyClass(const char* const in_name, unsigned const in_to_play_with = 0)
: to_play_with(in_to_play_with)
{
std::size_t length = std::strlen( in_name );
name = new char[length += 1];
memcpy(name, in_name, length);
++object_counter_prv;
std::cout << "\n AnyClass Constructor for: " << name << '\n';
}
AnyClass(AnyClass const &original) : to_play_with
(original.to_play_with)
{
std::size_t length = std::strlen( original.name );
name = new char[length += 9]; //9 = 8 + 1 (1 for the null
character)
memcpy( name, "Copy of " , 8 ); // . . .waste of a null
character
memcpy( &name[8], original.name, length -= 9 ); //Take the 9
back off
name[length += 8] = '\0';
++object_counter_prv;
std::cout << "\nAnyClass Copy Constructor for: " << name << '\n';
}
AnyClass& operator=(AnyClass const &other)
{
//NB: There is no name change whatsoever
to_play_with = other.to_play_with;
std::cout << "\n AnyClass Assignment Operator: " << name <<
" = " << other.name << '\n';
}
~AnyClass()
{
std::cout << "\n AnyClass Destructor for: " << name << '\n';
delete [] name;
--object_counter_prv;
}
};
unsigned AnyClass:bject_counter_prv = 0;
unsigned const &AnyClass:bject_counter = AnyClass:bject_counter_prv;
int main()
{
AnyClass blah("blah");
AnyClass poo = blah;
AnyClass toke = poo;
AnyClass monkey("monkey");
monkey = poo;
AnyClass cow(poo = blah = toke); // **** CORRUPTION ***
AnyClass cheese = AnyClass("cheese");
std::cout << blah.GetName() << '\n';
std::cout << poo.GetName() << '\n';
std::cout << monkey.GetName() << '\n';
std::cout << cow.GetName() << '\n'; // *** shows corruption again ***
std::cout << cheese.GetName() << '\n';
}
Can anyone spot the error?
-JKop