2017-07-27 5 views
-1

Ich habe eine serielle Kommunikationsbibliothek, die ich erstelle, und es ist eine verwaltete Assembly, die mit eigenen Regeln kommt (ich verstehe sie nicht vollständig, ich ändere nur Code, wenn VS beschwert), und ich habe ein Speicherleck, das ich nicht herausfinden kann.Visual C++ Speicherleck

Dies ist die Leckwarnung, die ich bekommen (Linie 11 ist der InfoContainer Konstruktor in 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. 

Dies ist die h-Datei für die lib:

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

und diese sind die relevanten CPP-Sektionen:

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

Der Grund, warum ich eine InfoContainer cl verwenden Ass und InfoContainer Pointer in der Hauptklasse ist, dass einige Informationen, die ich speichern muss, als nicht verwalteten Code und so kann ich es nicht direkt in der Hauptklasse haben.

Vielen Dank im Voraus!

+0

In VS Watch Window schreiben '_crtBreakAlloc', die den Wert = -1 hat. Setzen Sie nun seinen Wert auf 144. Dann sollte VS bei der 144. Zuweisung von Speicher brechen. – sergiol

Antwort

0

Das Problem ist _CrtDumpMemoryLeaks() wird aufgerufen, bevor alle Objekte gelöscht werden.

Sie benötigen einen Finalizer. Es folgt die „goldenen Muster“, wenn Sie eine Klasse in C++/CLI schreiben:

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

!SerialComm() 
{ 
} 

nicht virtuelle zu Ihrem destructor hinzuzufügen vergessen. Der Grund, warum virtueller Destruktor benötigt wird, sollte in jedem guten C++ - Lehrbuch erklärt werden.

+0

Ich verstehe nicht, was ich tun soll. Ich habe einen Finalizer erstellt und den Destruktor-Code in diesen verschoben, dann den Finalizer aus dem Destruktor aufgerufen, bekomme aber immer noch den Speicherleck, und jetzt bekomme ich eine SEHException, wenn ich versuche, den Handle zu schließen. –

+0

Können Sie mir Ihre * main() * Funktion zeigen? Verwenden Sie gcnew? Überprüfen Sie auch die Compileroption [Konfigurationseigenschaften] - [C/C++] - [Codegenerierung] - [C++ - Ausnahmen aktivieren] für SEHException. – JazzSoft

+0

Ich kompiliere das tatsächlich als eine gemanagte DLL. Ich kann gcnew nicht für den InfoContainer verwenden, da es nicht verwaltete Ressourcen enthält. Dies ist das wichtigste: https://gist.github.com/anonymous/0b24ad9df664cbce9a24bc57548d72dc. –