我一直在为我的数据网络课程做一个项目,我遇到了内存泄漏,但我不明白为什么会这样。
顺便说一句,我知道 C 和 C++ 的混合很糟糕,但我对此无能为力,它基于类代码,我无法修改它,我知道这不是一个好方法它和我需要使用 char* 作为必要条件。
我的程序是多线程的,我处理这个结构:
typedef struct packetQueue
{
char* buf;
int length;
packetQueue()
{
buf = nullptr;
length = 0;
}
packetQueue(char* buffer, int len)
{
length = len;
buf = new char[length + 1];
memcpy(buf, buffer, len);
buf[length] = '\0';
}
packetQueue(const packetQueue& other)
{
length = other.length;
if (other.buf)
{
buf = new char[length + 1];
memcpy(buf, other.buf, length);
buf[length] = '\0';
}
else
{
buf = nullptr;
}
}
packetQueue& operator=(const packetQueue& that)
{
if (this == &that)
{
return *this;
}
delete[] buf;
length = that.length;
if (that.buf)
{
buf = new char[length + 1];
memcpy(buf, that.buf, length);
buf[length] = '\0';
}
else
{
buf = nullptr;
}
return *this;
}
~packetQueue()
{
delete[] buf;
buf = nullptr;
}
} PACKET;
在我的带有两个参数的构造函数中,我做了那个赋值,因为我的队列的推送对我的结构做了一个深拷贝,就像我有我的拷贝构造函数一样,我已经处理了。所以,我有一个线程(我一直在测试,VLD结果只是针对这个)。
DWORD _stdcall PHY_in_Thread(void* data)
{
int numbytes, counter = 0;
SOCKET hostSocket = *(SOCKET*) data; // Socket where the host receives
struct sockaddr_in si_recvfrom;
struct sockaddr_storage their_addr;
socklen_t addr_len;
addr_len = sizeof their_addr;
while ( 1 )
{
char* recBuf = new char[BUFLEN + 1];
// Checks if it's any buffer on the socket to be processed
if ( (numbytes = recvfrom(hostSocket, recBuf, BUFLEN, 0, (sockaddr*) &si_recvfrom, &addr_len)) == -1)
{
cerr << "Could not receive datagram." << endl;
delete[] recBuf;
closesocket(hostSocket);
WSACleanup();
exit(0);
}
recBuf[numbytes] = '\0'; // append NULL to the end of the string
char* temporalBuffer = new char[numbytes - CHECKSUM_MAX_SIZE + 1];
memcpy(temporalBuffer, recBuf, numbytes - CHECKSUM_MAX_SIZE);
temporalBuffer[numbytes - CHECKSUM_MAX_SIZE] = '\0';
char extractedChecksum[CHECKSUM_HEX_SIZE + 1];
DWORD crcBuffer = crc32buf(temporalBuffer, numbytes- CHECKSUM_MAX_SIZE); // Calculates the CRC32 checksum
_snprintf(extractedChecksum, 8 , "%08lX", crcBuffer); // Prints the string in a buffer
extractedChecksum[CHECKSUM_HEX_SIZE] = '\0';
delete[] temporalBuffer;
string strExtractedChecksum = extractedChecksum; // Copies the array in a string
transform(strExtractedChecksum.begin(), strExtractedChecksum.end(), strExtractedChecksum.begin(), upper); // Uppercase the string
// Array for store the checksum of the packet
char readChecksum[CHECKSUM_MAX_SIZE + 1];
// Store the checksum of the packet in local variable
memcpy( readChecksum, &recBuf[numbytes - CHECKSUM_MAX_SIZE], CHECKSUM_MAX_SIZE);
readChecksum[CHECKSUM_MAX_SIZE] = '\0';
std::stringstream stream;
string strReadChecksum;
for (int i = 0; i < CHECKSUM_MAX_SIZE; i++ )
{
int number = static_cast<int>(readChecksum[i]); // Casts every character of the checksum array
if ( readChecksum[i] <= -1 ) // In case the int value it's negative adds the constant value to make that recognizable
{
number += 256;
}
// Convert the decimal number in a hex representation
stream.str("");
stream << hex << number;
if ( stream.str().length() < 2 ) // In case it's a number less than 10, adds a 0 at the beginning
{
strReadChecksum += "0" + stream.str();
}
else
{
// Working out the presentation of the number
strReadChecksum += stream.str();
}
}
std::transform(strReadChecksum.begin(), strReadChecksum.end(), strReadChecksum.begin(), upper); // Uppercase the string
strReadChecksum[CHECKSUM_HEX_SIZE] = '\0';
cout << "[PI] Frame #" << counter <<" received ("<< numbytes <<" bytes). " << endl;
if ( !strcmp(strReadChecksum.c_str(), extractedChecksum) ) // Checks if the CRC are equal
{
cout << "[CRC] Checksum OK: 0x" << extractedChecksum << endl;
}
else
{
cout << "[CRC] Checksum failure: 0x" << extractedChecksum << endl;
}
// Push the packet in the MAC_in_queue to be processed
MAC_in_queue.push(PACKET(recBuf, numbytes));
recBuf = nullptr;
counter++;
break; // Just for test one packet
}
MAC_in_queue.clear();
return 0;
}
但是当我执行这个线程并向这个线程发送一些东西以存储在这个队列中时,就会出现泄漏。在此执行中,只有一项可以使事情变得简单。
---------- Block 29 at 0x0068F718: 264 bytes ----------
Call Stack:
d:\program files (x86)\microsoft visual studio 11.0\vc\include\concurrent_queue.h (402): Host.exe!Concurrency::concurrent_queue<packetQueue,std::allocator<packetQueue> >::_Allocate_page + 0xF bytes
f:\dd\vctools\crt_bld\self_x86\crt\src\concurrent_queue.cpp (113): MSVCP110D.dll!Concurrency::details::_Micro_queue::_Push + 0xD bytes
f:\dd\vctools\crt_bld\self_x86\crt\src\concurrent_queue.cpp (240): MSVCP110D.dll!Concurrency::details::_Concurrent_queue_base_v4::_Internal_move_push
d:\program files (x86)\microsoft visual studio 11.0\vc\include\concurrent_queue.h (581): Host.exe!Concurrency::concurrent_queue<packetQueue,std::allocator<packetQueue> >::push + 0xF bytes
d:\users\silex rpr\documents\visual studio 2012\projects\project3\hoster\host.cpp (638): Host.exe!PHY_in_Thread + 0x3D bytes
0x7474339A (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes
0x76EC9EF2 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x63 bytes
0x76EC9EC5 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x36 bytes
Data:
00 00 00 00 01 00 00 00 60 F8 68 00 80 00 00 00 ........ `.h.....
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
但是我不明白这些数据泄漏在哪里,我希望我说清楚了。
预先感谢