データ ネットワーク コースのプロジェクトで作業していて、メモリ リークが発生しましたが、なぜ発生しているのかわかりません。
ところで、私は 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;
2 つのパラメーターを持つコンストラクターでは、キューのプッシュによって構造体のディープ コピーが実行され、コピー コンストラクターがあり、既にそれを処理しているように、その割り当てを行います。したがって、スレッドが 1 つあります (1 つずつテストしており、VLD の結果はこの 1 つのみです)。
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;
}
しかし、このスレッドを実行し、このスレッドに何かを送信してこのキューに格納すると、リークが発生します。この実行では、物事を単純にするための項目は 1 つだけです。
---------- 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 ........ ........
しかし、このデータがどこから漏れているのかわかりません。
事前に感謝