2017-07-27 77 views
-1

我有一个串行通信库,我正在创建,它是一个托管程序集,它附带了它自己的规则(我没有完全理解它们,我只是在VS抱怨时更改代码),而且我有一个内存泄漏,我无法弄清楚。Visual C++内存泄漏

这是泄漏警告,我得到(第11行是InfoContainer构造函数SERIALCOMM :: SERIALCOMM()):

Detected memory leaks! 
Dumping objects -> 
SerialComm.cpp(11) : {144} normal block at 0x011468B8, 56 bytes long. 
Data: <    > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
Object dump complete. 

这是LIB .h文件:

#include <windows.h> 
#include <stdlib.h> 
#include <atlstr.h> 

public class InfoContainer { 
public: 
    ~InfoContainer(); 
    HANDLE handle; 
    bool connected; 
    COMSTAT status; 
    DWORD errors; 
    DCB connection_params; 
    CStringA port_name; 
}; 

public ref class SerialComm { 
public: 
    InfoContainer* info=0; 
    SerialComm(); 
    ~SerialComm(); 
    bool OpenConnection(String^ Portname); 
    int CloseConnection(); 
    bool WriteData(String^ toSend); 
    String^ ReadData(int bytesToRead); 
}; 

而这些都是相关的.cpp部分:

SerialComm::SerialComm() { 
    info = new (_NORMAL_BLOCK, __FILE__, __LINE__) InfoContainer(); 
    info->handle = 0; 
} 
SerialComm::~SerialComm() { 
    CloseConnection(); 
    delete info; 
} 

bool SerialComm::OpenConnection(String^Portname) { 
    info->port_name = Portname; 

    //visual studio's valgrindish tool 
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); 
    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); 
    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); 
    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT); 
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); 
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); 
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 
    _CrtDumpMemoryLeaks(); 


    info->handle = CreateFileA(
     info->port_name, 
     GENERIC_READ | GENERIC_WRITE, 
     0, 
     NULL, 
     OPEN_EXISTING, 
     0, 
     NULL 

    ); 
    if (info->handle == INVALID_HANDLE_VALUE) { 
     ATLTRACE("Error: %d", GetLastError()); 
     printf("Error: %d\n", GetLastError()); 
     return false; 
    } 
    // 
    //rest of connection code here 
    // 
} 

int SerialComm::CloseConnection() { 
    return CloseHandle(info->handle); 
} 

InfoContainer::~InfoContainer() { 
    delete handle; 
} 

我之所以必须使用InfoContainer CL在主类中的ass和InfoContainer指针是我需要存储的一些信息被认为是非托管代码,所以我不能直接在主类中。

在此先感谢!

+0

在VS Watch窗口中写入_crtBreakAlloc值为-1。现在将它的值设置为144.然后,VS应该在第144个内存分配中断开。 – sergiol

回答

0

问题是_CrtDumpMemoryLeaks()在所有对象被删除之前被调用。您需要一个终结器。以下是“汇金模式”,当你写在C++/CLI类:

virtual ~SerialComm() 
{ 
    this->!SerialComm(); 
} 

!SerialComm() 
{ 
} 

不要忘记虚拟添加到您的析构函数。为什么需要虚拟析构函数应该在任何优秀的C++教科书中解释。

+0

我不明白我应该做什么。我做了一个终结器,并将析构函数代码移入该析构函数,然后从析构函数中调用终结器,但仍然发生内存泄漏,现在当试图关闭句柄时,我得到一个SEHException。 –

+0

你能告诉我你的* main()*函数吗?你使用gcnew吗?同时检查SEHException的编译器选项[配置属性] - [C/C++] - [代码生成] - [启用C++异常]。 – JazzSoft

+0

我实际上正在编译这是一个托管的DLL。我无法使用gcnew作为InfoContainer,因为它包含非托管资源。这是主要的:https://gist.github.com/anonymous/0b24ad9df664cbce9a24bc57548d72dc。 –