Sign in to follow this  
  • entries
    686
  • comments
    1952
  • views
    385714

Curse you pointers!!!

Sign in to follow this  
Stompy9999

69 views

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]
Sign in to follow this  


4 Comments


Recommended Comments

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.

Share this comment


Link to comment
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;
}

Share this comment


Link to comment
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.

Share this comment


Link to comment
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.

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now