Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

02.08.2013, 15:14

[Gelöst] Zugriffsverlezung bei Herunterfahren der selbstgeschriebenen Engine

hallo,
ein paar Freunde und ich wollten ein eigenes Spiel programmieren, und wollten deshalb eine Engine schreiben (über den Sinngehalt dieses Vorhabens geht es hier nicht).
Das Test-Spiel (eine Konsolenanwendung) inkludiert den Haupt-Header der Engine und initialisiert sie:
[spoiler]

C-/C++-Quelltext

1
2
3
4
5
6
#include <iostream>#include <wasdEngine.h>
using namespace wasd;
int wmain(){ bool fullscreen = false; wasdEngine engine(800, 500, fullscreen, "TestGame");
    engine.doRenderLoop();
    engine.destroy();
    return 0;}
[/spoiler]

Das Fenster öffnet sich ganz normal, die Engine wird korrekt initialisiert, allerdings wenn ich das Fenster schließe, kommt ein Fehler:
[spoiler]

Quellcode

1
Unbehandelte Ausnahme bei 0x0FCF485F (wasdEngine.dll) in testGame.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xCDCDCDCD
[/spoiler]

Der Compiler zeigt mir, das der Fehler bei der Destruktion des wasdDevice ensteht (Klasse, die die Interaktion mit dem D3D11Device erleichtert)

C-/C++-Quelltext

1
void wasdEngine::destroy(){ shader->~wasdShader();  device->~wasdDevice(); //<- Fehler  [...]}


Ich kann mir das allerdings nicht erklären.
[Spoiler]

C-/C++-Quelltext

1
wasdDevice::~wasdDevice(){  swapchain->Release();   dev->Release(); devcon->Release();  backbuffer->Release();}
[/spoiler]
Kann mir jemand helfen?

Wichtige Dateien:
wasdEngine.h
[spoiler]

C-/C++-Quelltext

1
2
3
4
5
6
#ifndef wasdEngine_H_#define wasdEngine_H_
#include <Windows.h>#include <SDL.h>#include <SDL_syswm.h>#include "..\src\Declarations.h"#include "..\src\wasdDevice.h"#include "..\src\wasdShader.h"//#include "..\src\wasdModel.h"#include "..\src\wasdObject.h"#include "..\src\Structs.h"#include "..\src\Enums.h"#include <D3D11.h>#include <D3DX10.h>#include <D3DX11.h>
namespace wasd{ class wasdShader;   class wasdDevice;
    class WASD_DLL_API wasdEngine   {   public:     wasdEngine(int width, int height, bool fullscreen, char* title);        void destroy();     ~wasdEngine();
        void doRenderLoop();                HWND getHWND();     int getWidth();     int getHeight();        //std::vector<wasdModel*> models;       //std::vector<wasd::wasdObject*> objects;
    private:        SDL_Surface* screen;        wasdDevice* device;     wasdShader* shader;     HWND hWnd;      int width, height;  };}#endif
[/spoiler]

wasdEngine.cpp
[spoiler]

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "..\shared\wasdEngine.h"#include <string>#include <stdio.h>#include "Declarations.h"#include <iostream>
using namespace wasd;
wasdEngine::wasdEngine(int width, int height, bool fullscreen, char* title){    wasdEngine::width = width;  wasdEngine::height = height;    //SDL initialisieren    SDL_Init(SDL_INIT_VIDEO);   //Erzeugung der SDL_Surface if(fullscreen)  {       screen = SDL_SetVideoMode(width, height, 32, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN);   }   else    {       screen = SDL_SetVideoMode(width, height, 32,SDL_HWSURFACE | SDL_DOUBLEBUF); }   if(!screen) {       MessageBox(NULL, L"Erstellung der SDLSurface fehlgeschlagen", L"Error", MB_ICONERROR | MB_OK);      exit(0);    }   else    {       std::cout<<"Initialisierung der SDLSurface erfolgreich\n";  }   SDL_WM_SetCaption(title, title);    SDL_SysWMinfo wminfo;   SDL_VERSION(&wminfo.version);   SDL_GetWMInfo(&wminfo); hWnd = wminfo.window;
    //wasdDevice erzeugen   device = new wasdDevice(hWnd, fullscreen, width, height);   if(!device) {       MessageBox(NULL, L"Erstellung des wasdDevices fehlgeschlagen", L"Error", MB_ICONERROR | MB_OK);     exit(0);    }
    //Shader erzeugen   shader = new wasdShader(device);    if(!shader) {       MessageBox(NULL, L"Erstellung des wasdShaders fehlgeschlagen", L"Error", MB_ICONERROR | MB_OK);     exit(0);    }}
void wasdEngine::destroy(){ shader->~wasdShader();  device->~wasdDevice();
    /*if(models.size() != 0)    {       for(int i = 0; i < models.size(); i++)      {           models[i]->~wasdModel();        }   }   for(int i = 0; i< objects.size(); i++)  {       objects[i]  }*/ SDL_FreeSurface(screen);    SDL_Quit();}
wasdEngine::~wasdEngine(){
}
HWND wasdEngine::getHWND(){ return hWnd;}
int wasdEngine::getWidth(){ return width;}
int wasdEngine::getHeight(){    return height;}
void wasdEngine::doRenderLoop(){    SDL_Event event;    bool running = true;
    while(running)  {       while(SDL_PollEvent(&event))        {           switch(event.type)          {           case SDL_QUIT: running = false; break;          }       }       device->RenderFrame();  }}
[/spoiler]
wasdDevice.h
[spoiler]

C-/C++-Quelltext

1
2
3
4
5
6
7
#ifndef wasdDevice_H_#define wasdDevice_H_
#include "Declarations.h"#include <D3D11.h>
namespace wasd{ class wasdDevice    {   public:
        wasdDevice(HWND hWnd, bool fullscreen, int width, int height);
        ~wasdDevice();
        void createVertexAndPixelShader(ID3D10Blob* VS, ID3D10Blob* PS, ID3D11VertexShader* pVS, ID3D11PixelShader* pPS);       void RenderFrame();
    private:        ID3D11Device* dev;      ID3D11DeviceContext* devcon;        IDXGISwapChain* swapchain;      ID3D11RenderTargetView* backbuffer;     DXGI_SWAP_CHAIN_DESC scd;   };}#endif
[/spoiler]
wasdDevice.cpp
[spoiler]

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "wasdDevice.h"#include "Structs.h"#include "Declarations.h"#include <iostream>
using namespace wasd;
wasdDevice::wasdDevice(HWND hWnd, bool fullscreen, int width, int height){
    ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
    scd.BufferCount = 1;    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;    scd.OutputWindow = hWnd;    scd.SampleDesc.Count = 4;  if(fullscreen)  {       scd.Windowed = FALSE;   }   else    {       scd.Windowed = TRUE;    }
    D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &scd, &swapchain, &dev, NULL, &devcon);
    //Adresse des Backbuffers bekommen  ID3D11Texture2D* pBackBuffer;   swapchain->GetBuffer(0, _uuidof(ID3D11Texture2D), (LPVOID*) &pBackBuffer);
    //bufferadresse benutzen um Render-Taget zu setzen  dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);    pBackBuffer->Release();
    //Backbuffer als Rendertarget setzen    devcon->OMSetRenderTargets(1, &backbuffer, NULL);
    //Viewport setzen   D3D11_VIEWPORT viewport;    ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
    viewport.TopLeftX = 0;  viewport.TopLeftY = 0;  viewport.Width = width; viewport.Height = height;
    devcon->RSSetViewports(1, &viewport);   pBackBuffer->Release();
    std::cout<<"Initialisierung des wasdDevice erfolgreich"<<std::endl;}
wasdDevice::~wasdDevice(){  swapchain->Release();   dev->Release(); devcon->Release();  backbuffer->Release();}
void wasdDevice::createVertexAndPixelShader(ID3D10Blob* VS, ID3D10Blob* PS, ID3D11VertexShader* pVS, ID3D11PixelShader* pPS){   dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);   dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
    devcon->VSSetShader(pVS, 0, 0); devcon->PSSetShader(pPS, 0, 0);}
void wasdDevice::RenderFrame(){ // clear the back buffer to a deep blue    devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
    swapchain->Present(0, 0);}
[/spoiler]
Vielen Dank

EDIT: Wieso formatiert er den code so komisch?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »SuperManitu« (05.08.2013, 11:13)


Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

2

02.08.2013, 15:17

0xCDCDCDCD? Sicher, dass alle Objekte, die du da freigeben willst auch initialisiert sind?
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

3

02.08.2013, 15:20

Ja, eigentlich schon

alle in wasdDevice::wasdDevice

FSA

Community-Fossil

  • Private Nachricht senden

4

02.08.2013, 15:26

Debugger genutzt und geguckt ob ein NULL Pointer vorhanden ist?

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

5

02.08.2013, 15:29

Ja, debugger habe ich benutz (visual c++ 2012 express), null pointer hat er nicht angezeigt.

6

02.08.2013, 15:33

Quellcode

1
2
shader->~wasdShader(); 
device->~wasdDevice();

Wieso rufst du den Destruktor manuell auf?
"Theory is when you know something, but it doesn’t work. Practice is when something works, but you don’t know why. Programmers combine theory and practice: Nothing works and they don’t know why." - Anon

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

02.08.2013, 15:41

Na damit der Code vom Compiler den auch nochmal aufruft und es dann klatscht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

8

02.08.2013, 15:52

(Kann man die Editor-Sicht nicht entfernen und nur den Quellcode bei Posts erlauben? Das tut doch weh, Leute... D: )
Ich sehe Pointer-Zugriffe, was auf die Verwendung des "new"-Operators hinweist. Wo "new" ist, gehört auch ein passendes "delete" hin. Immer. Das wird einem auf http://cppreference.com/ eigetrichtert, auf http://www.cplusplus.com/reference/ , so wie wahrscheinlich in jedem akzeptablen C++-Buch. Und sollten das gar Smart Pointer sein, entfällt fast immer das "delete" und somit auch der manuelle Destruktor-Aufruf.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

9

02.08.2013, 15:55

Das heißt ich muss nur delete bunutzen um den Destruktor aufzurufen

Hab in Sachen c++ - Objektorienierung geringere Kenntnisse, ich komme von Java.

EDIT: mit delete bekomme ich den gleichen fehler

10

02.08.2013, 16:04

durch delete hat sich der Fehler jetzt verschoben hin zu

C-/C++-Quelltext

1
delete shader;

der destruktor ist aber ähnlich dem von wasdDevice

EDIT: hab nochmal im debugger nachgeschaut, er kann aus irgeneinem grund überhaupt keine variabeln lesen, es heißt der speicher kann nicht gelesen werden

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »SuperManitu« (02.08.2013, 16:14)


Werbeanzeige