2013-09-24 86 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'语句。 –

相关问题