c++ - 使用 Char* 查找内存泄漏的原因

标签 c++ pointers memory-leaks

我一直在处理一些 char* 指针的项目中工作,并且使用 char* 而不是 std::string 是该类的必要条件,所以...

我有这个结构定义和这个队列:

typedef struct packetQueue
{
    char* buf;
    int length;

    packetQueue()
    {
        buf = new char[];
        length = 0;
    }

    } PACKET;

并发性::concurrent_queue IP_in_queue;

我有这个缓冲区:

char sendBuf[MSG_SIZE + sizeof (IP_PACKET_HEADER_T) + 1]; // String to be send

和我的新缓冲区的结构:

PACKET ipQueue;

然后我用这个填充我的缓冲区:

// Concatenates the header with sended message
memcpy(sendBuf, (void*)&sendHeader, sizeof(sendHeader));

memcpy(&sendBuf[sizeof(sendHeader)], readMessage, sendHeader.length);

ipQueue.buf = sendBuf;
ipQueue.length = packetSize;

然后我将我的数据包推送到我的队列 IP_in_queue.push(ipQueue);//将缓冲区推送到 IP_in_queue

这是我的循环以防万一:

while ( 1 )
{
    // Get the user input
    cout << "> ";
    cin.getline (buf, BUFLEN);

    IP_PACKET_HEADER_T sendHeader; // Store the header to be send
    PACKET ipQueue;

    char* fakeIPAddressDst, *readMessage; 

    delay = atoi(strtok (buf," ")); // Takes the first delay value
    fakeIPAddressDst = strtok (NULL, " "); // Stores the IP Address
    readMessage = strtok (NULL, " "); // Stores the sended message

    Sleep(delay); // Sleep the miliseconds defined

    // Fills the header with the data neccesary data
    sendHeader.DIP = inet_addr(fakeIPAddressDst);
    sendHeader.SIP = inet_addr(initAddress.fakeIpAddress);
    sendHeader.length = getStringLength(readMessage) + 1;
    packetSize = sizeof( sendHeader ) + sendHeader.length; // Defines the size of the packet to be send

    // Concatenates the header with sended message
    memcpy(sendBuf, (void*)&sendHeader, sizeof(sendHeader));
    memcpy(&sendBuf[sizeof(sendHeader)], readMessage, sendHeader.length);

    ipQueue.buf = sendBuf;
    ipQueue.length = packetSize;

    numbytes = packetSize; // The number of bytes of sended buffer

    char sendedString[BUFLEN + 1]; // Variable for stores the data
    IP_PACKET_HEADER_T readHeader; // To store the header for showing the information

    // Print out the content of the packet
    // Copy from buf to the header
    memcpy( (void*)&readHeader, ipQueue.buf, sizeof( IP_PACKET_HEADER_T));
    // Copy message part
    memcpy( sendedString, &ipQueue.buf[sizeof(IP_PACKET_HEADER_T)], numbytes - sizeof(IP_PACKET_HEADER_T));
    // Append \0 to the end
    sendedString[numbytes - sizeof(IP_PACKET_HEADER_T)] = '\0';

    // Save the IP information of the packet in a struct for print on the screen
    struct in_addr fakeAddrHost;
    fakeAddrHost.s_addr = readHeader.SIP;

    // Print the neccesary data
    cout << "[IN] DST: " << fakeIPAddressDst << endl; // Fake IP address of the destination
    cout << "[IN] SRC: " << inet_ntoa(fakeAddrHost) << endl; // Fake IP address of the host
    cout << "[IN] MSG: " << sendedString << endl ; // Message to send

    IP_in_queue.push(ipQueue); // Push the buffer in the IP_in_queue
}

我知道此过程中存在内存泄漏,但我不确定。 当我推送数据包时,buf 指针一直指向我的 sendBuf,对吗?因为分配是这样做的,但是如果我在推送程序崩溃后删除了 ipQueue 中的指针。我不得不说,在我将该结构插入队列后,另一个线程尝试弹出那个结构,显然如果我删除我的 ipQueue 指针,我将丢失我的缓冲区,那么我如何才能避免这种内存泄漏?

谢谢

编辑:

使用buf = nullptr定义的内存泄漏

---------- Block 1 at 0x0068BB30: 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 (232): MSVCP110D.dll!Concurrency::details::_Concurrent_queue_base_v4::_Internal_push
    d:\program files (x86)\microsoft visual studio 11.0\vc\include\concurrent_queue.h (566): Host.exe!Concurrency::concurrent_queue<packetQueue,std::allocator<packetQueue> >::push + 0xF bytes
    d:\users\silex rpr\documents\visual studio 2012\projects\project2\project2\host.cpp (802): Host.exe!main
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (536): Host.exe!__tmainCRTStartup + 0x19 bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (377): Host.exe!mainCRTStartup
    0x7662339A (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes
    0x77179EF2 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x63 bytes
    0x77179EC5 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x36 bytes

最佳答案

首先;这不是 C,您使用的是 C++ 编译器。 C 中的结构不能有方法和构造函数,并且 newdelete 不存在。

其次,您在构造函数中为 buf 分配了内存,但是...

ipQueue.buf = sendBuf;

这是一个漏洞。每次调用 new 时都需要调用 delete。您使用 new 分配了 buf,但从未对其调用 delete,因此内存泄漏。

我认为没有理由在这里分配 buf。只需将其设置为 null。

typedef struct packetQueue
{
    char* buf;
    int length;

    packetQueue()
        : buf(nullptr), length(0) { }
} PACKET;

附带说明一下,这是 C 和 C++ 的非常糟糕的混合。这是你们老师教你们的吗?

关于c++ - 使用 Char* 查找内存泄漏的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12556793/

相关文章:

java - C++ 与 Java 内存化差异

c++ - Variadic 模板匹配 const 和非常量 std::string 时遇到问题

C数组结构函数指针

c - 处理 CUDA 中指向指针的图像指针

ios - 内存泄漏 `NSLayoutConstraint`

c++ - 为什么 Armadillo 无法学习高斯混合模型并提示 'no existing means' 尽管随机子集播种?

c++ - 编译错误 C3861 Visual Studio 2010

c++ - 通过函数越来越深入地传递指针

iphone - 第二次加载 View 时内存泄漏

使用闭包回调的ios内存泄漏