SDL - error 0xC0000005

0

Witajcie , mam problem , jestem początkującym samoukiem w programowaniu, obecnie czytam książkę o SDL. Staram się postępować jak autor jednakże gdzieś chyba się pomyliłem i za chiny nie mogę dojść gdzie ;/
Visual wywala mi to :
First-chance exception at 0x00386CFE in Projekt1.exe: 0xC0000005: Access violation writing location 0x00000000.

Mógłbym prosic o radę?

(Nagłówek)

#include "SDL.h"
#ifndef __Game__
#define __Game__
class Game
{
public:
	Game();
	~Game();
	bool init(const char* title, int xpos, int ypos, int width, int
		height, int flags);
	void render();
	void update();
	void handleEvents();
	void clean();
	bool running() { return m_bRunning; }
private:
	SDL_Window* m_pWindow;
	SDL_Renderer* m_pRenderer;
	bool m_bRunning;
};
#endif 

(Plik źródłowy)

 #include <iostream>
#include <SDL.h>
#include "Nagłówek.h"

Game * g_game = 0;
int main(int argc, char* argv[])
{

	g_game->init("Chapter 1", 100, 100, 640, 480, 0);
	while (g_game->running())
	{
		g_game->handleEvents();

		g_game->render();
	}
	g_game->clean();
	return 0;
}


bool Game::init(const char* title, int xpos, int ypos, int width,
	int height, int flags)
{
	// attempt to initialize SDL
	if (SDL_Init(SDL_INIT_EVERYTHING) == 0)
	{
		std::cout << "SDL init success\n";
		// init the window
		m_pWindow = SDL_CreateWindow(title, xpos, ypos,width, height, flags);
		

		if (m_pWindow != 0) // window init success
		{
			std::cout << "window creation success\n";
			m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
			if (m_pRenderer != 0) // renderer init success
			{
				std::cout << "renderer creation success\n";
				SDL_SetRenderDrawColor(m_pRenderer,
					255, 255, 255, 255);
			}
			else
			{
				std::cout << "renderer init fail\n";
				return false; // renderer init fail
			}
		}
		else
		{
			std::cout << "window init fail\n";
			return false; // window init fail
		}
	}
	else
	{
		std::cout << "SDL init fail\n";
		return false; // SDL init fail
	}
	std::cout << "init success\n";
	m_bRunning = true; // everything inited successfully,start the main loop
	return true;
}
void Game::render()
{
	SDL_RenderClear(m_pRenderer); // clear the renderer tothe draw color
		SDL_RenderPresent(m_pRenderer); // draw to the screen
}
void Game::clean()
{
	std::cout << "cleaning game\n";
	SDL_DestroyWindow(m_pWindow);
	SDL_DestroyRenderer(m_pRenderer);
	SDL_Quit();
}
void Game::handleEvents()
{
	SDL_Event event;
	if (SDL_PollEvent(&event))
	{
		switch (event.type)
		{
		case SDL_QUIT:
			m_bRunning = false;
			break;
		default:
			break;
		}
	}
}
1
Game * g_game = 0;
int main(int argc, char* argv[])
{
 
    g_game->init("Chapter 1", 100, 100, 640, 480, 0);

Czego sie spodziewasz wołając metodę init() na wskaźniku bez przydzielonej pamięci? W ogóle w tym kodzie widzę masę gwiazdek a ani jednego new/malloc.

2

Nie używaj malloc, tylko new. Generalnie, jak Shalom powiedział - nie tworzysz obiektów. W C++ obiekty można tworzyć na dwa sposoby:

MyClass obj;
 

To jest sposób pierwszy. Tworzysz obiekt "automatyczny". Sama deklaracja jest utworzeniem obiektu - w taki sposób za pomocą konstruktora domyślnego. Jeśli chcesz użyć konkretnego konstruktora, to po prostu:

MyClass obj(parametry);

Tak utworzony obiekt zostanie automatycznie zwolniony. Tzn. jeśli np. utworzysz obiekt w funkcji, to przy wyjściu z funkcji on automatycznie zostanie zniszczony.

Drugi sposób utworzenia obiektu, to utworzenie go przez wskaźnik:

MyClass * obj;

tutaj tylko DEKLARUJESZ, że obj jest wskaźnikiem na obiekt klasy MyClass. Nie jest obiektem, tylko wskaźnikiem. Aby taki wskaźnik wskazywał na obiekt musisz go albo utworzyć, albo przypisać do już istniejącego. Tworzysz przez new:

MyClass * obj = new MyClass(); //lub new MyClass(parametry), jeśli chcesz użyć innego konstruktora

Tak stworzony obiekt MUSISZ samodzielnie zwolnić, gdy już go nie będziesz potrzebował. To, co stworzyłeś operatorem new, niszczysz operatorem delete:

 
delete obj;

Teraz różnica w wywoływaniu metod. Jeśli obiekt jest utworzony automatycznie, wtedy do jego wnętrza wchodzisz kropką:

 
MyClass obj;
obj.init();

Jeśli masz wskaźnik do obiektu, to wtedy do jego wnętrza wchodzisz strzałką:

 
MyClass * obj;
obj = new MyClass();

obj -> init();
delete obj;

Pewnie dałoby się też kropką w podobny sposób (sam się dopiero uczę C++ i nie testowałem tego, ale na logikę powinno zadziałać):

 
MyClass * obj = new MyClass();

(*obj).init();

delete obj;

Nawet, jeśli to działa, to zapis jest bez sensu i zaciemnia kod.

Jest też pośredni sposób tworzenia obiektów. Tzn. łączy jakby te dwa. Na pewno ma wpływ na szybkość, ale raczej niezauważalny przy zwykłych aplikacjach. Konkretnie chodzi o używanie...nie wiem dokładnie jak to się nazywa... "automatyczny wskaźnik" ?

Np:

 
auto_ptr <MyClass> obj = new MyClass();

obj jest niejako wskaźnikiem na obiekt klasy MyClass, ale nie musisz go zwalniać, ponieważ to jest automatyczny wskaźnik i w odpowiednim momencie POWINIEN zwolnić się sam. Są być może lepsze odpowiedniki w bibliotece boost, np: scoped_ptr lub shared_ptr. Każde z nich ma swoje zastosowanie. Generalnie użycie takiego mechanizmu z założenia powinno wyeliminować możliwość wystąpienia memory leaków. Czy tak jest w rzeczywistości? Nie wiem, bo z C++ mam zbyt małe doświadczenie. Natomiast na pewno ogranicza memory leaki.

0

Dziękuję wszystkim za odpowiedzi. Jak więc powinienem zmodyfikowac program? Bo próbowałem różnymi sposobami, zawsze coś jednak się nie zgadzało. ;(

0

Zdebuguj kod i zobaczysz, że błąd masz tu: g_game->init("Chapter 1", 100, 100, 640, 480, 0);
A teraz przeczytaj jeszcze raz mój post i zobacz, czego Ci brakuje. Przeczytaj też komentarz kq pod moim postem (RAII to te automatyczne wskaźniki).

I zapamiętaj - błąd typu AccessViolation zazwyczaj oznacza, że próbujesz dostać się do nieistniejącego obiektu.

0

Temat do zamkniecia. Problem nie był ze wskaznikiem, tylko z niepotrzebną funkcją game() utworzoną w nagłówku. Dziekuje za rady i informacje ;)

0

oczywiscie ze problem jest z wskaznikiem. Nie wierze ze kod (ten z poczatku w main) wyglada tak samo teraz u Ciebie a to co tutaj nam pokazales.

1 użytkowników online, w tym zalogowanych: 0, gości: 1