shared_ptr - Delete?
-
Sone schrieb:
Ich glaube so etwas nennt man monolithische Klasse...
Alle anderen klassen sind kleiner.
CData ist nur eine Datenklasse und soll eigentlich nichts machen außer die daten zwischen allen Klassen verwalten und Notifys an die Observer senden wenn auf bestimmte Sachen zugegriffen wurde.Wie gesagt... das Projekt ist groß.
-
Ja oder Gottklasse iVm Spaghetticode. Daten an einer einzigen Stelle zu halten klingt erstmal angenehm, bringt aber diverse Nachteile mit sich. Zumindest würde es in kleineren Datenobjekten sammeln. Aber gut, darum geht's hier ja gerade nicht.
Ich kann da so weit keine möglichen Speicherleaks erkennen. Es gibt keine custom classes, die hier instanziiert werden, new und delete werden ebenfalls nicht verwendet.
Aber ohne Instanziierung gibt es keine Speicherleaks? Vielleicht findet jemand anders was.
-
Des Rätzels Lösung:
std::vector<Observer*> m_obsWTarget[6]; std::vector<Observer*> m_obsTarget[6]; std::vector<Observer*> m_obsSvoAngle[6];
Erzeugt 18 Bytes leak im speicher...
Aber warum?Wieso ich das so gemacht habe:
Es Melden sich mehrere Observer an, Daher Vectoren.
Es Gibt 6 Beine, Daher hat jedes Bein, seinen Eigenen Observer Vector.edit:
hier nochmal alles relevante:#include "CData.h" int main(void) { CData data; _CrtDumpMemoryLeaks(); return 0; }
class Observer { public: virtual void notify_WTarget() = 0; virtual void notify_Target() = 0; virtual void notify_SvoAng() = 0; virtual void notify_BegScene() = 0; };
class CData { public: CData(){}; private: vector<Observer*> m_obsWTarget[6]; vector<Observer*> m_obsTarget[6]; vector<Observer*> m_obsSvoAngle[6]; vector<Observer*> m_obsBeginScene; };
-
Um mal was konstruktives beizutragen:
Das
vector<int> v(5); // alloziert globalen Speicher int main() { _CrtDumpMemoryLeaks(); // v hält undeleteden Speicher, CrtDump meint, es gibt einen Leak } // am Ende der main löscht v den Speicher, aber CrtDumpMemoryLeaks wurde schon vorher aufgerufen
Moral: nie globale Variablen nehmen und nicht CrtDumpMemoryLeaks nehmen, sondern richtige Profiler.
-
einfach herrlich schrieb:
Um mal was konstruktives beizutragen:
Das
vector<int> v(5); // alloziert globalen Speicher int main() { _CrtDumpMemoryLeaks(); // v hält undeleteden Speicher, CrtDump meint, es gibt einen Leak } // am Ende der main löscht v den Speicher, aber CrtDumpMemoryLeaks wurde schon vorher aufgerufen
Moral: nie globale Variablen nehmen und nicht CrtDumpMemoryLeaks nehmen, sondern richtige Profiler.
Interessant. Also tauchen bei mir einige Sachen als "Leaks" auf die garkeine sind?
Und was wäre denn sei ein richtiger Profiler?
-
Valgrind zum Beispiel.
Ich selbst komme aber auch eher mit crtDumpMemoryLeaks klar.
Aber globale Leaks findest du eher weniger damit
-
Korrigier mich, wenn ich falsch liege, aber ist _CrtDumpMemoryLeaks nicht eine MSVC-Funktion und Valgrind nur für Linux verfügbar?
-
Ja zu der MSVC Frage. Nein zu Valgrind. Ich meine es gibt das als Portierung auch für Windows.
Hier
Aber das sieht nach externen Entwicklern aus, daher wird wohl die Funktionalität eingeschränkt sein. Aber keine Ahnung, ich hab bisher nur auf Ubuntu mit Valgrind gearbeitet.
-
Dieses Valgrind ist eine Lib die mir soetwas wie "_CrtDumpMemoryLeaks()" gibt, nur das es etwas besser und tiefgehender greift?
PS: Ich hatte wohl nie leaks....
Ich habe jetzt alles so gebaut das ich die Freigabe bereits vor dem _CrtDumpMemoryLeaks() mache. Also nicht wie vorher mit erreichen vom Ende der Main.
Ich hab jetzt wieder das alte Programm von vor 3 Tagen mit veränderter main:
Und siehe da. Keine Leaks.#include "inc/init_configuration.h" #include "inc/render_frame.h" #include "inc/hexapod.h" #include "inc/control.h" #include "inc/GUI3D.h" #include "inc/Console.h" #include "inc/DirectX_Device.h" #include "inc/Cdata.h" #include "inc/_IStrategy.h" #include "inc/_IStrategyVal.h" CData* data = new CData(); DirectX_Device* dxdv = new DirectX_Device(data); #include "inc/win_api.h" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { RECT screen; screen.top = 0; screen.bottom = data->get_INI()->Data()->Screen_Height; screen.left = 0; screen.right = data->get_INI()->Data()->Screen_Width; AdjustWindowRect(&screen, WS_OVERLAPPEDWINDOW, false); int width, height; width = screen.right - screen.left; height = screen.bottom - screen.top; HWND hWnd; WNDCLASSEX wc; ZeroMemory(&wc, sizeof(WNDCLASSEX)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszClassName = "WindowClass"; RegisterClassEx(&wc); hWnd = CreateWindowEx(NULL, "WindowClass", "Lua-Engine", WS_OVERLAPPEDWINDOW, 0, 0, width, height, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); dxdv->set_instance(&hInstance, hWnd); _IStrategy :: m_CData = data; _IStrategyVal :: m_CData = data; Hexapod* hexa = new Hexapod(data); GUI3D* gui = new GUI3D(data); Console* cons = new Console(data); Control* ctrl = new Control(data, hexa, cons); MSG msg; while(!data->KillThisProcess()) { gui->start_clock(); data->refresh_temp_M(); while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } if(msg.message == WM_QUIT) break; data->calc_relative_M(); render_frame(dxdv, gui, ctrl, cons, data); gui->stop_clock(); } dxdv->clean_D3D(); delete ctrl; delete cons; delete gui; delete hexa; delete dxdv; delete data; _CrtDumpMemoryLeaks(); return EXIT_SUCCESS; }
Auch wenn ich noch interesse an diesem Valgrind habe, sage ich schon mal Dankeschön an alle die Tipps und Ideen eingebracht haben!
-
Und warum nutzt du überhaupt globale Variablen, wo du sie gar nicht brauchst?
Und Valgrind ist ein externes Tool.
-
Ja, aber es ersetzt beim Aufruf sämtliche Speicherallokationsfunktiond es Betriebssystems durch eigene Funktionen, und die protokollieren alle Informationen und können dir danach sagen, wie viel Speicher du gebraucht hast, wieder freigegeben hast oder eben nicht.
Dadurch läft das Programm jedoch nur noch sehr langsam.
-
Nathan schrieb:
Und warum nutzt du überhaupt globale Variablen, wo du sie gar nicht brauchst?
Für die Windowproc funktion "#inlcude ind/win_api.h"
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_DESTROY: PostQuitMessage(0); return 0; break; case WM_KEYUP: data->key_Up(wParam); break; case WM_KEYDOWN: data->key_Down(wParam); break; case WM_MOUSEMOVE: if( dxdv->get_device() ) { POINT ptCursor; GetCursorPos( &ptCursor ); data->set_Mouse(ptCursor); (dxdv->get_device())->SetCursorPosition( ptCursor.x, ptCursor.y, 0 ); } break; case WM_LBUTTONDOWN: data->set_MouseL(true); break; case WM_LBUTTONUP: data->set_MouseL(false); break; case WM_RBUTTONDOWN: data->set_MouseR(true); break; case WM_RBUTTONUP: data->set_MouseR(false); break; case WM_MOUSEWHEEL: data->set_Wheel(GET_WHEEL_DELTA_WPARAM(wParam)); break; case WM_ACTIVATEAPP: if(wParam) dxdv->reset_D3D(); break; } return DefWindowProc (hWnd, message, wParam, lParam); }