繁体   English   中英

可用内存分配产生异常-C ++

[英]Free Allocated Memory Generates Exception - C++

我的应用程序中有一个函数,其中分配了用于格式化端口名的内存。 调用CreateFile打开端口。 在函数末尾,调用free尝试释放已分配的内存。

DWORD CSerialPort::Open( wchar_t * port )
{
    DCB dcb = {0};
    LPTHREAD_START_ROUTINE pThreadStart;
    void * pvThreadData = NULL;
    wchar_t * pwcPortName = NULL;
    DWORD dwRetVal = ERROR_SUCCESS;

    /* Validate parameters. */

    pwcPortName = (wchar_t *)malloc( wcslen( port ) + 6 );

    if ( pwcPortName == NULL )
    {
        TRACE(_T("CSerialPort::Open : Failed to allocate memory for formatted serial port name.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ERROR_NOT_ENOUGH_MEMORY, __WFILE__, __LINE__);
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    memcpy( pwcPortName, L"\\\\.\\", 4 * 2 );
    memcpy( pwcPortName + 4, port, wcslen( port ) * 2 + 2 );

    // Get a handle to the serial port.
    _hSerialPort = CreateFile(
        pwcPortName,                    // Formatted serial port
        GENERIC_READ | GENERIC_WRITE,   // Access: Read and write
        0,                              // Share: No sharing
        NULL,                           // Security: None
        OPEN_EXISTING,                  // OM port already exists
        FILE_FLAG_OVERLAPPED,           // Asynchronous I/O
        NULL                            // No template file for COM port
        );

    if ( _hSerialPort == INVALID_HANDLE_VALUE )
    {
        TRACE(_T("CSerialPort::Open : Failed to get the handle to the serial port.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__);
        return ::GetLastError();
    }

    /* Initialize the DCB structure with COM port parameters with BuildCommDCB. */

    /* Set the serial port communications events mask with SetCommMask. */

    /* Set serial port parameters with SetCommState. */

    /* Set the serial port communications timeouts with SetCommTimeouts. */

    /* Create thread to handle received data with CreateThread. */

    free( pwcPortName );                 // <-- Exception thrown here.

    return dwRetVal;
}

谁能告诉我我在做什么错? 谢谢。

malloc分配字节,但是您正在使用分配的内存来存储wchar_t

您必须更改malloc size参数以匹配您现有的memcpy用法:

pwcPortName = (wchar_t *)malloc( wcslen( port ) + 6 );

应该

pwcPortName = (wchar_t *)malloc( (wcslen( port ) + 6) * sizeof(wchar_t));

更简单的解决方案:

DWORD CSerialPort::Open( std::wstring const& port )
{
    // ...
    std::wstring portname = L"\\\\.\\" + port;

    // Get a handle to the serial port.
    _hSerialPort = CreateFile(
        portname.c_str(), // ...

不用担心释放内存。 C ++现在会解决这个问题。

尝试:

pwcPortName = (wchar_t *)malloc( sizeof(wchar_t) * (wcslen( port ) + 6) );

...因为在Unicode应用程序中, wchar_t是两个字节。 您还必须在第二个memcpy调用中进行类似的更改。

但是,这是C ++ ,应该改为使用newdelete

pwcPortName = new wchar_t[wcslen( port ) + 6];

//...

delete[] pwcPortName;

这会更整洁:

DWORD CSerialPort::Open( wchar_t * port )
{
    DCB dcb = {0};
    LPTHREAD_START_ROUTINE  pThreadStart;
    void*     pvThreadData = NULL;
    DWORD     dwRetVal     = ERROR_SUCCESS;

    /* Validate parameters. */
    std::wstring  pwcPortName;

    pwcPortName.append(L"\\\\.\\");
    // memcpy( pwcPortName, L"\\\\.\\", 4 * 2 );
    //                                     ^^^ Whats this magic number? sizeof(wchar_t)
    //                                 ^^^ Is this one the size of the string?
    //                                     If you change the string you also need to
    //                                     modify the 4? Thats not good (hard to
    //                                     maintain (or should I say easy to break))
    pwcPortName.append(port);
    // memcpy( pwcPortName + 4, port, wcslen( port ) * 2 + 2 );
    //                      ^^^ Magic Number. Are you sure this is even correct?
    //                          Adding 4 to this moves the pointer 4 * sizeof(wchar_t)
    //                          So now you have an implied dependency on the above code
    //                          in this line. So if the string was changed you would need
    //                          to modify the 4 in two places!
    //                                               ^^^^^^^ * 2 + 2
    //                          Assume the * 2 is (* sizeof(wchar_t))
    //                          And the + 2 is (+ sizeof(wchar_t)) is to make sure
    //                          you copied the null terminator.                  

    // Get a handle to the serial port.
    _hSerialPort = CreateFile(
        pwcPortName.c_str(),            // Formatted serial port
        GENERIC_READ | GENERIC_WRITE,   // Access: Read and write
        0,                              // Share: No sharing
        NULL,                           // Security: None
        OPEN_EXISTING,                  // OM port already exists
        FILE_FLAG_OVERLAPPED,           // Asynchronous I/O
        NULL                            // No template file for COM port
        );


    // STUFF


    // No need to free the pointer as we used a std::Wstring to contain it
    // Thus it provides an exception safe memory leak free way of making sure
    // the memory is freeed.

    return dwRetVal;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM