Archived

This topic is now archived and is closed to further replies.

daerid

Really weird memory corruption error

Recommended Posts

I''ve got a basic Socket class that abstracts Overlapped Sockets using Winsock2. To manage the buffers I''ve created the following struct:
  
struct SockBuff : public WSABUF
{
  SockBuff(const unsigned int size)
    : BUFF_SIZE(size)
  {
    WSABUF::buf = new char[BUFF_SIZE];
    WSABUF::len = BUFF_SIZE;
  }
  ~SockBuff()
  {
    delete [] buf;
  }
  const unsigned int BUFF_SIZE;
};
  
This seems to work fine. However, under heavy loads, the destructor ( specifically the delete [] buf; call ) gives me an error, in the form of a Debug Assert Failed message box, stating that damage has been done to the block of memory that buf points to. Anybody have any idea what''s this all about? I can''t seem to track it down.

Share this post


Link to post
Share on other sites
WSABUF is a Winsock2.h defined struct. I didn''t write it, Microsoft did.

it''s definition looks like this:


  
typedef struct __WSABUF {
u_long len;
char FAR *buf;
} WSABUF, FAR * LPWSABUF;

Share this post


Link to post
Share on other sites
It could mean you have a buffer overrun problem with something else on the heap, that has trashed the magic numbers that the VC debugger speckles the heap with in debug mode.

Or it could mean you deleted it twice.

If you''re using STL port, why not make it a vector of WSABUF? perhaps somewhere you''re attempting to use more WSABUF''s than you have allocated.

Is this an asyncronous implementation? I had problems with the damn thing snarfing the buffers for extended periods of time - they''d come back in blocks of 183 all at once under heavy load.

Share this post


Link to post
Share on other sites
Don''t inherit for something that doesn''t have a virtual destructor.

Otherwise, the error message says that you''ve stomped on memory outside your allocated range, nothing to do with inheritence. I suggest cutting your program down to using one buffer (if possible), and setting a breakpoint on memory--specifically the 4 guard bytes before and after the allocated block of memory. This should cause your program to stop on the precise line that over/underwrites the buffer.

Share this post


Link to post
Share on other sites
It''s an Overlapped Socket Implementation.

I fixed it though, by adding a member char array of the size I needed, and just setting WSABUF::buf to that.

Share this post


Link to post
Share on other sites
quote:
Original post by daerid
It''s an Overlapped Socket Implementation.

I fixed it though, by adding a member char array of the size I needed, and just setting WSABUF::buf to that.


You may not have actually "fixed" it. The problem was most likely that you went past the buffer size in an adjacent buffer and overwrote the value of the next buffer''s "buf" pointer, thus the delete[] was trying to delete a different address then what was assigned by new. In theory, this could still be happening, but since you''re not deleting the buf anymore, you won''t see the error. Be sure when you''re writing to these buffers that you don''t go past the size of the buffer. Try putting an assert in your destructor that compares WSABUF::buf to your local char array address to see if you''re somehow still overwriting the WSABUF::buf. If I''m right, you should see it fail.

Share this post


Link to post
Share on other sites
quote:
Original post by cgoat
You may not have actually "fixed" it. The problem was most likely that you went past the buffer size in an adjacent buffer and overwrote the value of the next buffer''s "buf" pointer, thus the delete[] was trying to delete a different address then what was assigned by new.


That would actaully generate the "invalid block" error, not the "damage" error. But you are correct, it was probably caused by running past the buffer size in an array.

quote:

In theory, this could still be happening, but since you''re not deleting the buf anymore, you won''t see the error. Be sure when you''re writing to these buffers that you don''t go past the size of the buffer. Try putting an assert in your destructor that compares WSABUF::buf to your local char array address to see if you''re somehow still overwriting the WSABUF::buf. If I''m right, you should see it fail.


I agree that this is probably still happening, but the pointer itself is probably fine--I don''t think your assert will do anything. The main point is that "delete" is not the problem--that''s just the point at which the program finds out that there is a problem. Removing the delete is akin to just ignoring error codes. Again, I suggest either watching or putting breakpoints on the memory areas before and after your allocated buffer. When you see their values change, you''ve found your problem.

Share this post


Link to post
Share on other sites