2013-09-24 118 views
0

這裏是我的代碼:這段代碼爲什麼會拋出一個訪問衝突異常?

#include <SFML/Window.hpp> 
#include <SFML/Graphics.hpp> 
#include <SFML/Text.hpp> 
#include <iostream> 

using namespace std; 

class Game 
{ 
    private: 

     bool kratka[9]; 
     bool tak; 

     sf::RenderWindow okno; 

     sf::Image ikolo; 
     sf::Image ikrzyz; 

     sf::Texture tkolo; 
     sf::Texture tkrzyz; 

     sf::Sprite kolo[9]; 
     sf::Sprite krzyz[9]; 

     sf::Sprite minkz; 
     sf::Sprite minko; 

     sf::Vector2f vec; 
     sf::Vector2i mouse; 

     sf::Font font; 

     sf::Text Gracz1; 
     sf::Text Gracz2; 

     sf::Text wynik1; 
     sf::Text wynik2; 

     sf::Texture tkrata; 
     sf::Texture spowtorz; 

     sf::Sprite powtorz; 
     sf::Sprite skrata[9]; 
     int ikr[9]; // zmienne odpowiadajace za logiczna wartosc kraty 
     int rzad[8]; //kombinacje rzedow 

     int player1; 
     int player2; 

     string sp1; 
     string sp2; 

     void update_licznik(); 

     static const int krata=150; 

     void process(); 
     void update(); 
     void render(); 

     bool jestna(sf::Sprite &sp); 
     bool gracz; 

    public: 
     Game(); 
     void run(); 
}; 

Game::Game():okno(sf::VideoMode(800,600,32),"Kolko i krzyzyk") 
{ 
    tkrata.loadFromFile("sprites/kratka.png"); 
    ikolo.loadFromFile("sprites/kolo.png"); 
    ikrzyz.loadFromFile("sprites/krzyz.png"); 
    spowtorz.loadFromFile("sprites/powtorz.png"); 
    ikrzyz.createMaskFromColor(sf::Color(255,255,255),0); 
    ikolo.createMaskFromColor(sf::Color(255,255,255),0); 

    okno.setFramerateLimit(30); 

    tkolo.loadFromImage(ikolo); 
    tkrzyz.loadFromImage(ikrzyz); 

    minkz.setTexture(tkrzyz); 
    minkz.setPosition(670,270); 
    minkz.setScale(0.7,0.7); 

    minko.setTexture(tkolo); 
    minko.setPosition(0,270); 
    minko.setScale(0.7,0.7); 

    for(int i=0;i<3;i++) 
    { 
     for(int j=0;j<3;j++) 
     { 
      kolo[3*i+j].setTexture(tkolo); 
      krzyz[3*i+j].setTexture(tkrzyz); 
      kolo[3*i+j].setPosition(i*150+175,j*150+75); 
      krzyz[3*i+j].setPosition(i*150+175,j*150+75); 
     } 
    } 

    font.loadFromFile("sprites/poseiAOE.ttf"); 
    Gracz1.setFont(font); 
    Gracz1.setString("Gracz 1"); 
    Gracz1.setCharacterSize(70); 

    Gracz2.setFont(font); 
    Gracz2.setString("Gracz 2"); 
    Gracz2.setCharacterSize(70); 
    Gracz2.setPosition(650,0); 

    wynik1.setFont(font); 
    wynik2.setFont(font); 
    wynik1.setCharacterSize(300); 
    wynik2.setCharacterSize(300); 
    wynik1.setPosition(25,0); 
    wynik2.setPosition(700,0); 

    powtorz.setTexture(spowtorz); 
    powtorz.setPosition(640,440); 

    player2=0; 
    player2=0; 

    for(int i=0;i<9;i++) 
    { 
     ikr[i]=0; 
     rzad[i]=0; 
    } 
    for(int i=0;i<3;i++) 
    { 
     for(int j=0;j<3;j++) 
     { 
      skrata[3*i+j].setTexture(tkrata); 
      skrata[3*i+j].setPosition(i*150+175,j*150+75); 
     } 
    } 


} 

void Game::update_licznik() 
{ 
    sp1=to_string(player1); 
    sp2=to_string(player2); 
    wynik1.setString(sp1); 
    wynik2.setString(sp2); 
} 


bool Game::jestna(sf::Sprite &sp) 
{ 
    vec=sp.getPosition(); 
    mouse=sf::Mouse::getPosition(okno); 

    if(mouse.x>vec.x && mouse.x<vec.x+krata && mouse.y>vec.y && mouse.y<vec.y+krata) 
     return true; 
    else 
     return false; 
} 

void Game::process() 
{ 
    sf::Event zdarzenie; 
    while(okno.pollEvent(zdarzenie)) 
    { 
     for(int i=0;i<9;i++) 
     { 
      if(zdarzenie.type==sf::Event::MouseButtonPressed && jestna(skrata[i]) && ikr[i]==0) 
      { 
       gracz=!gracz; 
       if(gracz) 
        ikr[i]++; 
       else 
        ikr[i]--; 
      } 
      if(zdarzenie.type==sf::Event::MouseButtonPressed && jestna(powtorz)) 
      { 
       for(int i=0;i<9;i++) 
       { 
        ikr[i]=0; 
       } 
      } 
     } 

     if(zdarzenie.type==sf::Event::Closed) 
      okno.close(); 
    } 
} 

void Game::update() 
{ 
    update_licznik(); 
    rzad[0]=ikr[0]+ikr[1]+ikr[2]; 
    rzad[1]=ikr[0]+ikr[3]+ikr[6]; 
    rzad[2]=ikr[2]+ikr[5]+ikr[8]; 
    rzad[3]=ikr[6]+ikr[7]+ikr[8]; 
    rzad[4]=ikr[3]+ikr[4]+ikr[5]; 
    rzad[5]=ikr[1]+ikr[4]+ikr[7]; 
    rzad[6]=ikr[0]+ikr[4]+ikr[8]; 
    rzad[7]=ikr[2]+ikr[4]+ikr[6]; 
    for(int i=0;i<8;i++) 
    { 
     if(rzad[i]==3) 
     { 
      player1++; 
      rzad[i]=0; 
      for(int i=0;i<9;i++) 
       ikr[i]=0; 

     } 
     if(rzad[i]==-3) 
     { 
      player2++; 
      rzad[i]=0; 
      for(int i=0;i<9;i++) 
       ikr[i]=0; 
     } 
    } 
} 

void Game::render() 
{ 
    okno.clear(); 
    for(int i=0;i<9;i++) 
    { 
     okno.draw(skrata[i]); 
     if(ikr[i]==1) 
      okno.draw(kolo[i]); 
     if(ikr[i]==-1) 
      okno.draw(krzyz[i]); 
    } 
    okno.draw(Gracz1); 
    okno.draw(Gracz2); 
    okno.draw(wynik1); 
    okno.draw(wynik2); 
    okno.draw(powtorz); 
    okno.draw(minkz); 
    okno.draw(minko); 
    okno.display(); 
} 

void Game::run() 
{ 
    while(okno.isOpen()) 
    { 
     process(); 
     update(); 
     render(); 
    } 
} 

int main() 
{ 
    Game game; 
    game.run(); 
    return 0; 
} 

我每次運行此代碼,我得到以下異常:

Unhandled exception at 0x505D4361 (msvcr110d.dll) in Gra1.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC 
+0

您應該減少代碼以獲得[sscce](http://sscce.org/)。它有助於發現你在哪裏崩潰。另外,一個調試器將幫助**一個LOT **。 – Hiura

+0

在'Game'構造函數中'rzad [i] = 0;''由於'rzad [8]'將會是最後一次迭代中的溢出。另外,你初始化'player2'兩次,你省略了'player1'。 – ch0kee

回答

-1

當它崩潰大多是東西,你應該有一個調試搞清楚,但看着代碼,就有很多錯誤。

上面的代碼甚至不應該編譯,因爲SFML/Text.hpp不是有效的頭文件。

using namespace std;大多是壞事,如果它在全球範圍內完成,那麼這樣做顯然是錯誤的。命名空間是爲了:a)防止名稱衝突和b)使類明顯來自何處,因此在大多數情況下,您不應該使用名稱空間。

每個變量都需要初始化。如果它是一個具有默認構造函數的類,則不需要執行任何操作,但如果它是一個intbool,則必須對其進行初始化,否則您將運行一個未定義行爲的應用程序,這意味着它可能會炸燬任何時候。由於您使用的是類,因此您應該在構造函數的初始化列表中初始化變量,就像使用窗口一樣。

正如ch0kee在評論中指出的,rzad會遇到溢出。不幸的是,應用程序可能仍會繼續運行,因爲在數組中最後一個元素之後訪問元素是一個有效的指針,並且如果將0指定給它,在某些情況下可能會幸運。即使「指針」有效,也不應寫入或讀取其底層內容。您可以通過使用std::vector或使用C++ 11 std::array來阻止此類問題,從而使數據與其大小相結合,從而實現準確無誤的邊界檢查。

proccess()update()你使用for循環遍歷數組了,但你使用多次索引變量i,從而掩蓋其他指數。你應該總是使用不同的索引進行嵌套循環,不僅可以使用更高級的索引,而且可以減少混淆。

最後一句話,你可能想寫英文的變量名。使用母語進行編程是可以的,但只要您向該語言非本地人請求幫助,其他人就會在理解您的應用程序的意義時遇到問題。

如果你修復上面所說的話,它不應該再崩潰了。通過在編譯時激活更高級別的錯誤檢查是一件寶貴的事情,因爲它會通過警告告訴你很多錯誤。

+0

你對使用的命名空間信息是正確的,但在這種情況下,它似乎只是一個大的媽媽cpp文件,所以爲了測試起見,使用命名空間更容易,更少打字。但是你是對的,永遠不要在頭文件中使用'using'語句。 –

相關問題