2017-07-27 28 views
-1

私は作成しているシリアル通信ライブラリを持っています。これは独自のルールが付いているマネージドアセンブリです(私はそれらを完全に理解していません、VSは文句を言うとコードを変更します)。私が理解できないメモリリークVisual C++のメモリリーク

これは私が取得漏れの警告である(ライン11はSERIALCOMMでInfoContainerコンストラクタである:: 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); 
}; 
私はInfoContainer CLを使用する必要が

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; 
} 

理由:

これらは、関連する.cppセクションですメインクラスのインスツルとインフォコンテナポインタは、格納する必要のある情報はアンマネージコードとみなされるため、メインクラスで直接使用することはできません。

ありがとうございます!

+0

VSウォッチウィンドウで、値が-1の '_crtBreakAlloc'を書き込みます。その値を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として実際にコンパイルしています。管理対象リソースが含まれているため、InfoContainerにgcnewを使用することはできません。これがメインです:https://gist.github.com/anonymous/0b24ad9df664cbce9a24bc57548d72dc。 –