• Advertisement
Sign in to follow this  

Problem with boost:smart_ptr - invalid pointer?

This topic is 4155 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
No - I removed the ping code so nothing is sent and it runs fine. That narrows it down a bit.

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
I'd post the project (Linux only) but I don't have anywhere to host the files.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.....

Share this post


Link to post
Share on other sites
The whole point of smart pointers is that you never call delete on the pointer they hold. It gets deleted automatically.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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()?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement