I’m reading through an example in primer and something which it talks about is not happening. Specifically, any implicit shallow copy is supposed to copy over the address of a pointer, not just the value of what is being pointed to (thus the same memory address). However, each of the pos properties are pointing to two different memory addresses (so I am able to change the value of one without affecting the other). What am I doing wrong?
Header
#include "stdafx.h"
#include <iostream>
class Yak
{
public:
int hour;
char * pos;
const Yak & toz(const Yak & yk);
Yak();
};
END HEADER
using namespace std;
const Yak & Yak:: toz(const Yak & yk)
{
return *this;
}
Yak::Yak()
{
pos = new char[20];
}
int _tmain(int argc, _TCHAR* argv[])
{
Yak tom;
tom.pos="Hi";
Yak blak = tom.toz(tom);
cout << &blak.pos << endl;
cout << &tom.pos << endl;
system("pause");
return 0;
}
You’re printing the addresses of the pointers, not the address of the string they’re pointing to:
They are two different pointers, so their addresses differ. However, they point to the same string:
(Note that cast
static_cast<void*>(tom.pos). As Aaron pointed out in a comment, it is necessary because when outputting achar*will throughoperator<<, the stream library will assume the character pointed to to be the first character of a zero-terminated string. Outputting avoid*, OTOH, will output the address.)Note that there is more wrong with your code. Here
You are creating a new object. Its constructor allocates 20 characters, and stores their address in
tom.pos. In the very next lineyou are assigning the address of a string literal to
tom.pos, thereby discarding the address of the bytes you allocated, effectively leaking that memory.Also note that
Yakhas no destructor, so even if you don’t discard the 20 characters that way, whentomgoes out of scope,tom.poswill be destroyed and thus the address of those 20 bytes lost.However, due to your missing copy constructor, when you copy a
Yakobject, you end up with two of them having theirposelement pointing to the same allocated memory. When they go out of scope, they’d both try to delete that memory, which is fatal.To cut this short: Use
std::string. It’s much easier. Get a grip on the basics, using safe features of the language like thestd::string, the containers of the stdandard library, smart pointers. Once you feel sure with these, tackle manual memory management.However, keep in mind that I, doing C++ for about 15 years, consider manual resource management (memory is but one resource) error-prone and try to avoid it. If I have to do it, I hide each resource behind an object managing it – effectively falling back to automatic memory management.
:)Which “primer” is this you’re reading? Lippmann’s C++ Primer? If so, which edition? I’d be surprised if a recent edition of Lippmann’s book would let you lose onto dynamic memory without first showing your the tools to tackle this and how to use them.