|
-
April 23rd, 2012, 08:38 AM
#1
[RESOLVED] Help with memory leak
Hi. I'm having problems with my code. First of all i think i should mention i'm doing some sockets prgraming (non-MFC). Everything is working fine, however,
Code:
_CrtDumpMemoryLeaks()
is telling me that there's a memory leak. I did some research and i found out that it appears after these lines of code:
Code:
//char buff[257]
//wchar_t dataBuff[257]
//std::wstring *data - this is a valid pointer passed to function
received += singleRecv;
buff[singleRecv] = '\0';
mbstowcs_s(&converted, dataBuff, 257, buff, singleRecv);
*data += dataBuff;
Text with wich memory leak appears to be is 9 symbols. These are pretty much all variables wich gets in touch with it but it seems that none of these variables' address matches memory leak address. I think this might be silly mistake or something i'm overlooking but i can't find it. Hopefully you can Didn't felt a need to burden this post with whole function code, but feel free tell me if you need it.
Thanks in advance,
Fire_
Last edited by fire_; April 23rd, 2012 at 08:55 AM.
-
April 23rd, 2012, 09:51 AM
#2
Re: Help with memory leak
 Originally Posted by fire_
Hi. I'm having problems with my code.
What is "converted"?
Code:
mbstowcs_s(&converted, dataBuff, 257, buff, singleRecv);
*data += dataBuff;
In general, it helps if you posted the entire code, so we know what the declaration of everything is supposed to be.
In addition:
Code:
received += singleRecv;
buff[singleRecv] = '\0';
How do we know what the value of "singleRecv" is? Also, your databuff and buf are commented out, so who knows what they really are.
Last, why not write a simple program and call just that one function. Is there a memory leak in that simple program? There is no need to attach a giant function -- all you need to do is write a simple program, 3 or 4 lines, that sets up those arrays, calls the mbstowcs_s() function, and then exits. Then you check if there are memory leaks. If there aren't any, then there is nothing wrong with mbstowcs_s(), given that it is processing "good" data.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; April 23rd, 2012 at 09:58 AM.
-
April 24th, 2012, 12:22 AM
#3
Re: Help with memory leak
Last, why not write a simple program and call just that one function. Is there a memory leak in that simple program? There is no need to attach a giant function -- all you need to do is write a simple program, 3 or 4 lines, that sets up those arrays, calls the mbstowcs_s() function, and then exits. Then you check if there are memory leaks. If there aren't any, then there is nothing wrong with mbstowcs_s(), given that it is processing "good" data.
Regards,
Paul McKenzie
Thanks for answer. I already tried that and there's no memory leaks in there. So here's the full code of functions:
Main class declaration
Code:
class CWINSOCK_API CWinSock
{
public:
CWinSock();
CWinSock(const CWinSock&);
~CWinSock();
// Initialize WinSock
int Initialize(WORD version = 0x101);
// Shutdown WinSock
void Deinitialize();
// Sends packet directly and returns amount of data sent (blocking)
int SendPacket(SOCKET s, wchar_t *data, DWORD Flag);
// Reads packet from stream and returns if CRC is correct (blocking)
bool ReceivePacket(SOCKET s, PACKET *packet);
// Receives data chunk
int ReceiveData(SOCKET s, std::wstring *data, int len);
private:
// Lookup table array
ULONG crc32_table[256];
// Builds Lookup table array
void Init_CRC32_Table();
// Reflects CRC bits in the lookup table
ULONG Reflect(ULONG ref, char ch);
// Creates a CRC from a string buffer
int Get_CRC(wchar_t* text);
};
Function to received specific amount of data. Memory leak appears here
Code:
int CWinSock::ReceiveData(SOCKET s, std::wstring *data, int num)
{
if(num <= 0)
return -1;
int received = 0, singleRecv = 0;
size_t converted;
char buff[257];
wchar_t dataBuff[257];
_CrtDumpMemoryLeaks();
singleRecv = recv(s, buff, num, NULL);
_CrtDumpMemoryLeaks();
if(singleRecv > 0)
{
received += singleRecv;
buff[singleRecv] = '\0';
mbstowcs_s(&converted, dataBuff, 257, buff, singleRecv);
*data += dataBuff;
}
_CrtDumpMemoryLeaks(); // That's where memory leak first appears
DWORD start = GetTickCount();
while(received < num && (GetTickCount()-start)<250)
{
singleRecv = recv(s, buff, num-received, NULL);
if(singleRecv > 0)
{
received += singleRecv;
buff[singleRecv] = '0';
mbstowcs_s(&converted, dataBuff, 257, buff, singleRecv);
*data += dataBuff;
}
}
return received;
}
Code to get crc of packet
Code:
int CWinSock::Get_CRC(wchar_t* text)
{
ULONG ulCRC(0xffffffff);
int len;
wchar_t* buffer;
len = wcslen(text);
buffer = (wchar_t*)text;
while(len--)
ulCRC = (ulCRC >> 8) ^ crc32_table[(ulCRC & 0xFF) ^ *buffer++];
return ulCRC ^ 0xffffffff;
}
Simple function to convert wchar to bytes array. Used in main function so included for clarity
Code:
void wcharToBytes(wchar_t *src, unsigned char *dest, int num)
{
char temp[2];
size_t converted;
for(int i=0; i<num; i++)
{
if(src[i] != 0)
{
wcstombs_s(&converted, temp, 2, &src[i], 1);
dest[i] = (BYTE)temp[0];
}
else
dest[i] = 0;
}
}
Main function wich calls ReceiveData()
Code:
bool CWinSock::ReceivePacket(SOCKET s, PACKET *packet)
{
_CrtDumpMemoryLeaks();
int DataLen, CRC;
std::wstring buff;
BYTE bytes[4];
size_t converted;
ZeroMemory(bytes, 4);
int received = 0;
int packetCRC = 0;
// HEADER
// Get data length
received = ReceiveData(s, &buff, 4);
wcharToBytes((wchar_t*)buff.c_str(), bytes, 4);
memcpy_s(&DataLen, 4, bytes, 4);
if(received != 4)
return false;
// Get data CRC
received = ReceiveData(s, &buff, 4);
wcharToBytes((wchar_t*)buff.c_str(), bytes, 4);
memcpy_s(&CRC, 4, bytes, 4);
if(received != 4)
return false;
// TODO: Add resend if couldn't read all data from stream
// TODO: Add get flag
// BODY
// Get data
std::wstring dataBuff;
received = 0;
if(DataLen)
{
received = ReceiveData(s, &dataBuff, DataLen); // Leak appears in this call
_CrtDumpMemoryLeaks();
if(received < DataLen)
Sleep(30);
// TODO: Add resend packet if too small
packet->body.data = dataBuff;
packetCRC = Get_CRC((wchar_t*)dataBuff.c_str());
}
// Fill packet structure
_CrtDumpMemoryLeaks();
packet->header.CRC = CRC;
packet->header.size = DataLen;
// Check CRC of received packet
if(packetCRC != CRC)
return false;
else
return true;
}
Thanks in advance,
Fire_
Last edited by fire_; April 24th, 2012 at 12:25 AM.
-
April 24th, 2012, 03:20 AM
#4
Re: Help with memory leak
you're not using CrtDumpMemoryLeaks correctly. _CrtDumpMemoryLeaks checks if all memory allocations in the process heap have been freed at the point of its call. Hence, invoking it in the middle of your program will give false positives. For example
Code:
int main()
{
char* p = new char;
_CrtDumpMemoryLeaks();
delete p;
}
clearly, this program has no memory leaks as it is, but _CrtDumpMemoryLeaks comlpains anyway. Call it at the end of the program ( or wherever all heap resources are expected to be released ) instead.
-
April 24th, 2012, 04:06 AM
#5
Re: Help with memory leak
 Originally Posted by fire_
Thanks for answer. I already tried that and there's no memory leaks in there.
Well, as superbonzo stated, you're using the CrtDumpMemoryLeaks incorrectly. Of course if you stick that call in the middle of running code, especially code where you're concatenating onto a wstring, you will get a memory leak report.
CrtDumpMemoryLeaks is obviously going to say you have a memory leak, since the wstring variables have not gone out of scope yet, which is where the deallocation of the string data occurs.
Regards,
Paul McKenzie
-
April 24th, 2012, 07:52 AM
#6
Re: Help with memory leak
Ok... As I guessed earlier it was a silly mistake :P Thank you very much, you saved me hours of further research
Last edited by fire_; April 24th, 2012 at 07:58 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|