new kann keinen Speicher allokieren? Warum?



  • Ja nicht Windows selbst, sondern das Programm...

    Das Programm hängt sich an dieser Stelle auf. Habs mit ner Messagebox ausgetestet. Steht sie vor der Anweisung, wird sie noch angezeigt, steht sie danach, kommt sie nicht mehr. Wählt man dann aber "debug" in der Windows Fehlermeldung, so zeigte diese einem an, dass der genaue Fehler in irgend einer Windows Datei liegt, die den Befehl "malloc" definiert.

    Nun aber zeigt er auf einmal das der Fehler in nem ganz anderem Teil der Applikation aufgetreten sein soll. Dort angeblich beim Ende einer Funktion. also der "}". Jetz bin ich noch verwirrter.



  • Ich sollte noch hinzufügen, das der Fehler aber wirklich an der besagten Stelle bei der Speicherinitialisierung ausgelöst wird.

    keiner der da ne Ahnung hat?



  • zeig doch mal was nach dem new ... steht, aber nicht nur eine zeile



  • kokunze schrieb:

    Ich sollte noch hinzufügen, das der Fehler aber wirklich an der besagten Stelle bei der Speicherinitialisierung ausgelöst wird.

    keiner der da ne Ahnung hat?

    Lerne: Es gibt einen erheblichen Unterschied zwischen "ausgelöst" und "verursacht". Die Speicehrverwaltung bemerkt was immer Du vorher falsch gemacht hast eben erst beim Aufruf von new und wirft deswegen eine Excpetion.

    Deshalb muß new den Fehler aber noch lange nicht "verursachen". Sie es mal so, wenn Dir jemand 100 Euro aus der Tasche klaut, dann bist Du ja nicht automatisch der Dieb nur weil Du nachschaust und es bemerkst, oder?

    Der Fehler wird garantiert irgendwo anders erzeugt. Und ohne etwas mehr Code als die 2 Zeilen wird Dir da hier auch niemand helfen können.



  • Ja das Problem ist das das Program über 10 dateien geht und mehr als 5000 Zeilen Code besitzt. Also das new den Fehler auslöst, der woanders verursacht wird ist schonmal ein Ansatz. Das bedeuted das der Fehler bei irgend einer anderen Speicherallokierung liegen muss, oder? Hier mal was davor und danach passiert:

    void EngineMainLoop(void)
    {
    	MSG message;   // Windows Nachrichten Handle	
    
    	while(g_App.GetD3DStatus())			// D3D Zustand überprüfen
    	{
    		if(PeekMessage(&message,NULL,0,0,PM_REMOVE))		// Nachrichten auswerten
    		{
    			TranslateMessage(&message);
    			DispatchMessage(&message);
    		}
    
    		if(g_App.CheckDevice())				// Wenn Device nicht verloren ist:
    		{	
    			// Key Countdown  runterzählen
    			if (g_iKeyCountdown > 0)
    				g_iKeyCountdown--;
    
    			if (g_iMenu == 0)					// Wenn man nicht im Menu ist
    			{
    				// Das Bild Rendern
    				RenderScene();	
    
    		                  // am Ende dieser Funktion (RenderScene()) sagt der Debugger inzwischen das der Fehler aufgetreten ist
    
    				// Direct Input Objekt updaten
    				g_pInput->Update();
    
    				// Eingaben prüfen		
    				ReadKeyInput();
    
    // Diese Funktion (ReadKeyInput()) löst dann die Ladefunktion aus
    
    				ReadMouseInput();
    
    // ...
    // Hier folgen Funktionen zum Rotieren der 3D Objekte
    // ...
    
    			}
    			else
    			{			
    				// Menu rendern
    				RenderMenu();				
    			}
    		}	
    
    	}	// ~while(g_App.GetD3DStatus());
    
    }	// ~EngineMainLoop();
    
    void ReadKeyInput()
    {
    
    // ...
    // Viele Viele Abfragen für Tastendrücke
    //
    
    	if (g_pInput->KeyPressed(DIK_V))
    	{
    		if (g_iVernissageMode == 0)
    		{
    			if (!LoadVernissageFile()) return;
    
    			g_iVernissageMode = 1;
    			g_iVernissageRow = 0;
    		}
    		else
    		{
    			g_iVernissageMode = 0;
    		}
    	}
    
    }	// ~ReadKeyInput();
    
    bool LoadVernissageFile()
    {
    	FILE *fp;	
    	int iLine=0;	
    
    	 char* sBuffer = new char[256];
    
    // ...
    // zu Testzwecken alles auskommentiert was die eigentliche Dateiverarbeitung ist
    // ...
    
    	if (iLine > 0) 
    		return true;
    	else
    		return false;
    }	// ~LoadVernissageFile();
    

    So, da hab ich mal die 3 Funktionen zusammengeschnitten, die nacheinander aufgerufen werden.


  • Mod

    Es liegt nahe zu vermuten, dass der Fehler relativ nahe vor der Stelle liegt. etwa in RenderScene() oder g_pInput->Update()
    Mit dem Debugger und debug heap funktionen sollte das nicht zu schwer zu finden sein, alternativ kannst du ja noch
    delete [] new char[256]
    an allen möglichen Stellen einfügen, um die Quelle zu lokalisieren



  • kokunze schrieb:

    Ja das Problem ist das das Program über 10 dateien geht und mehr als 5000 Zeilen Code besitzt. Also das new den Fehler auslöst, der woanders verursacht wird ist schonmal ein Ansatz. Das bedeuted das der Fehler bei irgend einer anderen Speicherallokierung liegen muss, oder?

    Nicht zwingend bei der Allokierung. Wenn Du debug-code erzeugst fordert new nicht einfach nur Speicher an sondern macht eine ganze Reihe von Checks ob der Speicher zwischenzeitlich corrumpiert wurde. Ein new selbst kann den Speicher nicht korrumpieren, was Du suchst ist fehlerhafte Freigabe von Speicher, so ind er Art von doppeltem delete-Aufruf oder delete auf ein vorher nicht initialisiertem pointer usw. Wenn Du dir z.B. ein Ojekt anschaust und da sowas wie 0xfeefee drinsteht, dann ist das kein zufall sondern ein vom debug-delete eingetragener Wert um Dir anzuzeigen, daß dieser Speicehr freigegeben wurde. Findest Du sowas in einem Objekt mit dem Du (noch) arbeitest, grenzt das den Fehler schonmal ein...

    Wobei solche Fehler erfahrungsgemäß für einen Anfänger schwer zu finden sind...



  • blarghs son schrieb:

    Ein new selbst kann den Speicher nicht korrumpieren, was Du suchst ist fehlerhafte Freigabe von Speicher, so ind er Art von doppeltem delete-Aufruf oder delete auf ein vorher nicht initialisiertem pointer usw. Wenn Du dir z.B. ein Ojekt anschaust und da sowas wie 0xfeefee drinsteht, dann ist das kein zufall sondern ein vom debug-delete eingetragener Wert um Dir anzuzeigen, daß dieser Speicehr freigegeben wurde. Findest Du sowas in einem Objekt mit dem Du (noch) arbeitest, grenzt das den Fehler schonmal ein...

    Hm, vielen Dank schonmal, das ist ein Anfang. Werd das morgen nochmal anschaun. Leider kann ich den Debugger nur eingeschränkt nutzen. Wenn ich Debug starte, dann läuft zwar das Programm als Task, aber das Fenster in dem alles stattfindet öffnet sich nirgends. Keine Ahnung warum. Einzige Möglichkeit ist das Programm als .exe zu compilen, auszuführen und dann beim Absturz auf "debuggen" klicken.

    Vielleicht liegts ja irgendwo in der RenderScene(). Wenn ihr noch weitere ideen oder Tips hättet, woran es liegen könnte,bin ich sehr dankbar.



  • Also zum Problem selber nicht, aber beim Debuggen nehm ich mal an das du die DirectX Anwendung nicht im Vollbildmodus ausführst. Ansonsten änder das am besten mal, damit dein Debugger (und alle anderen Windowsprogramme) es leichter haben 😉



  • Nur so, koennt ja sein schrieb:

    Also zum Problem selber nicht, aber beim Debuggen nehm ich mal an das du die DirectX Anwendung nicht im Vollbildmodus ausführst. Ansonsten änder das am besten mal, damit dein Debugger (und alle anderen Windowsprogramme) es leichter haben 😉

    Hab beides schon gemacht. Derzeit läufts im Fenstermodus, damit nicht das ganze Windows sich bei dem Fehler aufhängt. Im Vollbild geht dann nämlich gar nix mehr.

    Also hab nun den Fehler eingegrenzt. Es handelt sich tatsächlich um einen Speicherfehler, danke an die, die mich auf den Pfad gebracht haben. Allerdings kann ich ihn nirgends finden. Ich hab nur 2 dynamische Variablen in der Anwendung. Diese werden beide mit new initialisiert und mit delete gelöscht (danach auch noch mit var = NULL; auf Nullzeiger gesetzt).

    Der Fehler tritt auch auf, wenn man das Programm normal beendet, also wenn das erste der beiden deletes aufgerufen wird. Dann sagt er:
    Unhandled exception at 0x7c920f29 in Test.exe: 0xC0000005: Access violation reading location 0x20bbbbff.

    Als Datei zeigt er dann die "free.c" (muss ne Windows Datei sein) und áuf:

    retval = HeapFree(_crtheap, 0, pBlock);
    if (retval == 0)
    {
     errno = _get_errno_from_oserr(GetLastError());
    }
    

    Noch ne Idee?
    Ich hab nun wirklich alles durchgeschaut. Keine doppelten news oder deletes. Keine Nutzung von uninitialisierten Variablen, etc



  • Du versuchst Speicher an der Adresse 0x20bbbbff freizugeben. Kann mich ja irren, aber das sieht nicht nach einer zulässigen Adresse aus, wobei ich jetzt nicht aus dem Kopf das Speichermapping von Windoof kenne, aber allein die 2 am Anfang erscheint mir bogus.

    Schau doch mal im Call stack nach welches delete den fehler auslöst...



  • Also ich habs nun weiter eingrenzen können. Hab jetzt nur noch eine einzige dynamische Struktur. Diese Speichert Vertex-Daten für das Rendering. Nun hängt es von der Anzahl der Objekte ab, ob es abstürzt oder nicht. Mal schaun ob da ne Berechnung falsch ist oder so.



  • Vielleicht versuchst du einen Zeiger zu löschen, der schon auf Null gesetzt wurde.



  • geloescht schrieb:

    Vielleicht versuchst du einen Zeiger zu löschen, der schon auf Null gesetzt wurde.

    Es ist kein fehler einen auf 0 stehenden Zeiger zu löschen. Da passiert einfach nix. z.B.

    char* ptr = 0;
    
    delete ptr;
    

    Hat ein klar definiertes Verhalten. da passierts chlicht gar nix.


Anmelden zum Antworten