Skip to main content
GameDev.net gamedev.net
🔒 Locked

Problem with boost:smart_ptr - invalid pointer?

Started by stodge Sep 20, 2006 at 2:18 PM 16 replies 2.2k views
Original Post
stodge
stodge
I'm using boost::smart_ptr and creating instances of a smart pointer in a tight loop. I create the object, use it and then delete it. I print out the pointer using std::cout and for the first 62 iterations, the value is always the same. On the 63rd iteration, the pointer value I see printed out is different. At this point my program crashes as the pointer dereferenced by the smart pointer is invalid. Is there some memory resource I'm exhausting here? It's coincidental it's always the same iteration that fails. I'm using Fedora Core 2 on GCC 3.3.3, but I've tested it with the same problem on PCLinuxOS, using GCC 4. I'd post some more code, but it's quite complex due to the class structure, so I'll try to pick and post bits out later if I have time. Thanks
---------------------http://www.stodge.net
deathkrush
deathkrush
Please post the tight loop snippet.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
stodge
stodge
Maybe tight wasn't the right word!

		HBMessagePacketPtr pack = 				hbMessagePacketFactory::GetSingleton().					CreatePacket(	hbProtocol::CMD_CHAT_SEND_MESSAGE,									hbMessagePacket::HB_RELIABLE &									hbMessagePacket::HB_ORDERED);			mConnection->Send(pack);						if (pack)				delete pack;


This is what's "in" the loop, but mConnection->Send(pack) invokes a whole bunch of code.....

So it's no help just posting this.
---------------------http://www.stodge.net
deathkrush
deathkrush
First of all, you don't need "if (pack) delete pack". In C++ it's okay to delete a null pointer. What happens if you comment out the mConnection->Send(pack); line? Does it still crash the same way?
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
stodge
stodge
No - I removed the ping code so nothing is sent and it runs fine. That narrows it down a bit.
---------------------http://www.stodge.net
stodge
stodge
Something must be trashing the stack -> now after a full rebuild, when I call:

mConnection->Send(pack);

The debugger actually goes into a completely object & function!
---------------------http://www.stodge.net
deathkrush
deathkrush
Do you have any recursive functions and do you ever pass large objects by value?
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
stodge
stodge
No and I don't think so.
---------------------http://www.stodge.net
stodge
stodge
I'd post the project (Linux only) but I don't have anywhere to host the files.
---------------------http://www.stodge.net
deathkrush
deathkrush
Try stepping through the code line by line and watching the EBP and ESP registers in your debugger's register window. Whenever the values in those registers get too small, you are about to corrupt the stack.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
stodge
stodge
No they're fine - when the segmentation violation happens their values are reasonable. It could be KDBG getting fooled by BOOST. It looks like the correct functions are being called but KBDG is maybe showing something wrong.
---------------------http://www.stodge.net
Enigma
Enigma
I'm confused. You say you're using Boost.Smart_Ptr. Where? HBMessagePacketPtr clearly isn't a smart pointer since you're explicitly deleting it.

Σnigma
stodge
stodge
HBMessagePacketPtr is just a typedef for the smart pointer.

The call stack is:

client->tick() // creates packet.
connection->Send(packet) // packet is valid and accessible.
connection->SendTo(packet) // packet is valid and accessible.
protocol->SendTo(packet) // packet appears to be valid in the debugger (ddd) but it is NOT accessible. It segfaults the application.

So in protocol->SendTo(packet), any attempt to use the pointer causes a segfault. Packet can be used/accessed by any function above in the call stack.

I'm so confused.....
---------------------http://www.stodge.net
stodge
stodge
I realise that now thanks. But that's irrelevant to this particular problem isn't it? I mean, there are no side effects of me deleting smart pointers.
---------------------http://www.stodge.net
jpetrie
jpetrie
In theory, yes, there are -- you circumvent the natural lifetime management the smart pointer is doing. It is fatal to delete a pointer managed by a smart pointer class.

In practice, HBMessagePacketPtr cannot be a boost::shared_ptr if that code compiles, because you cannot call delete on a boost::shared_ptr. It is not itself a pointer, and it provides no implicit conversion to the underlying pointer object (at least, not in the header I'm looking at).
stodge
stodge
It's definitely a shared pointer.

I found the problem. If the packet isn't consumed by a protocol layer (connection throttler etc..) then a message queue entry is created and the packet is stored in it. The message queue entry is then added to a message queue to be sent later.

If I completely ignore the queue and just send the packet once I know the protocol layers haven't consumed the packet then the application doesn't segfault.

So my message queue logic is wrong.

Thanks again
---------------------http://www.stodge.net
DrEvil
DrEvil
So if your message queue is storing the packet, presumably by having a shared_ptr to the same object, and you are then calling delete on it? I would guess this leaves the shared_ptr in the message queue in a jacked up state. Don't ever call delete on a shared_ptr, whether thats the problem here or not. Call .reset() if you want to clear a particular shared_ptr.

I'm pretty surprised if that is compiling, it sure doesn't in msvc 2005. Sure you aren't calling delete pack.get()?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.