Curse you pointers!!!

Published May 31, 2007
Advertisement
First off, I admit that I suck with using pointers. I try to avoid them whenever possible, but sometimes it simply isn't avoidable in order to achieve the best results.

Now I'm going to ask a question about pointers that is probably very simple, even though an hour of searching on google has yielded nothing.

I'm currently working on my Gamepad class, which contains seven pointers of type PadCommand. PadCommand is an abstract base class, so the pointers are meant to be dynamically allocated to one of the base classes.

I'm currently writing the copy constructor for the Gamepad class:
Gamepad(const Gamepad &g){    name = g.name;    // Set pointers equal down here}


The problem is, when I set the pointers equal it does a soft copy of the pointer, so the pointers point to the exact memory address of the pointers from the other Gamepad object. The result is, when the other Gamepad object memory is freed, the pointers in this object become garbage, because they were pointing to those addresses.

So basically, how do I make a copy of a dynamically allocated pointer so that the new pointer is the same object without pointing to the same memory address?

Sorry if my explaination sucks, I've been at this for awhile now and am quite tired. Any help would be appreciated.

Ugh, I should've used smart pointers[lol]
Previous Entry Gamepads work
Next Entry You're Winnar!
0 likes 4 comments

Comments

Trapper Zoid
Smart pointers would probably solve the problem.

Unfortunately I'm zonked out myself due to winter insomnia (stupid winter); so my intellectual output is greatly diminished today. If I gather what you are trying to do correctly you want to make sure that your copies still can access the memory after the original is freed, right?

If so, a common solution is to use reference counting for your pointers. Your Gamepad class can contain a variable to count how many objects have a reference to it. When something new grabs a copy, inrement the counter, when something releases one, decrement it. When the counter reaches zero, destroy the object. That way you'll be sure to only free the object when nothing still has a pointer to it.

I'm pretty sure that boost::shared_ptr works this way, so I'd use that if you can. But it's not too hard to put in the counter yourself if you'd prefer to do it that way.
May 31, 2007 10:32 PM
LachlanL
Does the PadCommand class have a copy constructor? If it does, just do:

Gamepad(const Gamepad &g)
{
    name = g.name;

    // Set pointers equal down here
    thePointer1 = new PadCommand(g.thePointer1);
    thePointer2 = new PadCommand(g.thePointer2);
    thePointer3 = new PadCommand(g.thePointer3);
    thePointer4 = new PadCommand(g.thePointer4);
    thePointer5 = new PadCommand(g.thePointer5);
    thePointer6 = new PadCommand(g.thePointer6);
    thePointer7 = new PadCommand(g.thePointer7);
}

This should perform a "deep" copy and allocate new memory for the new PadCommands. This way, the new Gamepad object will have its own copy of the data.

A copy constructor for PadCommand might look like:

PadCommand(const PadCommand& a)
{
    somePadCommandMember = a.somePadCommandMember;
}

May 31, 2007 10:48 PM
Stompy9999
Quote:Smart pointers would probably solve the problem.

Unfortunately I'm zonked out myself due to winter insomnia (stupid winter); so my intellectual output is greatly diminished today. If I gather what you are trying to do correctly you want to make sure that your copies still can access the memory after the original is freed, right?

If so, a common solution is to use reference counting for your pointers. Your Gamepad class can contain a variable to count how many objects have a reference to it. When something new grabs a copy, inrement the counter, when something releases one, decrement it. When the counter reaches zero, destroy the object. That way you'll be sure to only free the object when nothing still has a pointer to it.

I'm pretty sure that boost::shared_ptr works this way, so I'd use that if you can. But it's not too hard to put in the counter yourself if you'd prefer to do it that way.


That's a pretty good idea that I hadn't considered. I could probably keep them around until they're sure that they're not being referenced anymore, and then free them. I'll try this, although I'm not sure if it provides a solution to the immediate problem.

Quote:Original post by LachlanL
Does the PadCommand class have a copy constructor? If it does, just do:
*** Source Snippet Removed ***
This should perform a "deep" copy and allocate new memory for the new PadCommands. This way, the new Gamepad object will have its own copy of the data.

A copy constructor for PadCommand might look like:
*** Source Snippet Removed ***


The problem is that PadCommand is abstract, and a pointer to PadCommand would really be allocated like:
PadCommand *p = new ButtonCommand(0);

I don't know how to write a copy constructor for PadCommand that would accomadate that.

That does, however, give me the idea to create a copy constructor for PadCommand. I had just assumed before that I should just create one for Gamepad, but it makes more sense to have one for the actual pointers too.

May 31, 2007 11:02 PM
Stompy9999
Thanks! The idea about creating a copy constructor for PadCommand led me to look up copy constructors for abstract base classes. That led me to finding this method, which solved the problem. There are, ofcourse, alot more problems with the code, but I'll get them tomorrow, now that I don't have to focus on this one.
May 31, 2007 11:28 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement
Advertisement