2015-04-22 32 views
1

我已经添加了这些功能,我的代码,我的程序崩溃开始随机显示在0x6C7B52E7(SDL2.dll)在SDL_2.exe 未处理的异常:0000005:访问冲突写入位置0xFF00000C。调试器显示完全随机的代码片段,之前完美运行,这让我想到,这些新功能混淆了内存。C++可以构造错误违反写入位置

void ObstacleSet::move() 
{ 
Obstacles.push_back(Obstacle(mScreenWidth, mScreenHeight/6 + 100, 10, 10, Coin, -29, 0)); 
Obstacles.push_back(Obstacle(mScreenWidth, mScreenHeight/6 + 120, 10, 10, Coin, -29, 0)); 
Obstacles.push_back(Obstacle(mScreenWidth, mScreenHeight/6 + 140, 10, 10, Coin, -29, 0)); 
Obstacles.push_back(Obstacle(mScreenWidth, mScreenHeight/6 + 160, 10, 10, Coin, -29, 0)); 
Obstacles.push_back(Obstacle(mScreenWidth, mScreenHeight/6 + 180, 10, 10, Coin, -29, 0)); 

for (auto &i : Obstacles) 
    { 
     i.move(); 
    } 
} 

void ObstacleSet::outCheck(unsigned int &score) 
{ 
    for (unsigned int i = 0; i < getSize();) 
    { 
     if (getVelX(i) < 0 && (getX(i) + getW(i) <= 0)) 
     { 
      eraseObstacle(i); 
      score++; 
     } 

     else if (getVelX(i) > 0 && (getX(i) >= mScreenWidth)) 
     { 
      eraseObstacle(i); 
      score++; 
     } 

     else if (getVelY(i) > 0 && (getY(i) + getH(i) >= mScreenHeight)) 
     { 
      eraseObstacle(i); 
      score++; 
     } 

     else if (getVelY(i) < 0 && (getY(i) <= 0)) 
     { 
      eraseObstacle(i); 
      score++; 
     } 

     else 
     { 
      ++i; 
     } 
    } 
} 

显然,我有一些内存泄漏,或悬挂指针以某种方式出现,但我只是无法看到在哪里。也许我有一个错误的构造函数或其他东西。

ObstacleSet是一个类,它包含列表中的所有障碍物。

#ifndef MOBSTSET_H 
#define MOBSTSET_H 

#include <SDL.h> 
#include <cstdlib> 
#include "my_OBSTACLES.h" 
#include <list> 

class ObstacleSet 
{ 
public: 

ObstacleSet(int ScreenWidth, int ScreenHeight); 

int mScreenWidth; 
int mScreenHeight; 

void clear(); 

//Function, that moves the set depending on current time 
void move(); 

//Render set on screen 
void render(SDL_Renderer *Renderer); 

unsigned int getSize(); 

float getX(int); 
float getY(int); 
int getW(int); 
int getH(int); 
float getVelX(int); 
float getVelY(int); 
Type GetType(int); 

void eraseObstacle(int); 

void outCheck(unsigned int &score); 

std::list<Obstacle>::iterator getEnd(); 

private: 

//Vector to hold all obstacles 
std::list <Obstacle> Obstacles; 

}; 
#endif 

这些出现在我的游戏主循环此起彼伏

障碍类的头

#ifndef MYOBSTACLE_H 
#define MYOBSTACLE_H 

#include <SDL.h> 
#include <cmath> 
#include <vector> 
#include <cstdlib> 

enum Type 
{ 
Wall, 
Coin 
}; 

class Obstacle 
{ 
public: 
Obstacle(); 

//Initializer with parameters 
Obstacle(float x, float y, int w, int h, Type type, float VelocityX = 0, float VelocityY = 0); 

float VelocityX = 0; 
float VelocityY = 0; 

float xPos; 
float yPos; 

int mWidth; 
int mHeight; 

//Type of obstacle 
Type OBSType; 

//Render obstacle on screen 
void render(SDL_Renderer *Renderer); 

//Move obstacle 
void move(); 

int mRed = 200; 
int mGreen = 200; 
int mBlue = 20; 
bool color_up = false; 
}; 

#endif 

这些是我的障碍

Obstacle::Obstacle() : xPos(10), yPos(10), mWidth(10), mHeight(10), VelocityX(0), VelocityY(0), OBSType(Coin), mRed(200), mGreen(200), mBlue(20), color_up(false) 
{ 
    printf("Obstacle created!"); 
} 

Obstacle::Obstacle(float x, float y, int w, int h, Type type, float velocityX, float velocityY) : xPos(x), yPos(y), mWidth(w), mHeight(h), VelocityX(velocityX), VelocityY(velocityY), OBSType(type), mRed(200), mGreen(200), mBlue(20), color_up(false) 
{ 

} 

这里的构造是ObstacleSet的一些功能

void ObstacleSet::eraseObstacle(int number) 
{ 
    unsigned N = number; 
    std::list<Obstacle>::iterator i = Obstacles.begin(); 
    if (Obstacles.size() > N) 
    { 
     std::advance(i, N); 
    } 
     Obstacles.erase(i); 
} 

unsigned int ObstacleSet::getSize() 
{ 
    return Obstacles.size(); 
} 

float ObstacleSet::getX(int number) 
{ 
    unsigned N = number; 
    std::list<Obstacle>::iterator i = Obstacles.begin(); 
    if (Obstacles.size() > N) 
    { 
     std::advance(i, N); 
    } 
    return i->xPos; 
} 

std::list<Obstacle>::iterator ObstacleSet::getEnd() 
{ 
    return Obstacles.end(); 
} 

SDL初始化代码

bool init() 
{ 
    //Initialization flag 
    bool success = true; 

    //Initialize SDL 
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0) 
    { 
     printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError()); 
     success = false; 
    } 
    else 
     //Set texture filtering to linear 
     if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")) 
     { 
      printf("Warning: Linear texture filtering not enabled!"); 
     } 

    //Initialize SDL_mixer 
    if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) 
    { 
     printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError()); 
     success = false; 
    } 

    //Check for joysticks 
    if (SDL_NumJoysticks() < 1) 
    { 
     printf("Warning: No joysticks connected!\n"); 
    } 
    else 
    { 
     //Load joystick 
     gGameController = SDL_JoystickOpen(0); 
     if (gGameController == NULL) 
     { 
      printf("Warning: Unable to open game controller! SDL Error: %s\n", SDL_GetError()); 
     } 
    } 

    //Create window 
    gWindow = SDL_CreateWindow("Jello demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); 
    if (gWindow == NULL) 
    { 
     printf("Window could not be created! SDL Error: %s\n", SDL_GetError()); 
     success = false; 
    } 
    else 
    { 
     //Create vsynced renderer for window 
     gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); 
     if (gRenderer == NULL) 
     { 
      printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError()); 
      success = false; 
     } 
     else 
      //Initialize renderer color 
      SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF); 

     //Initialize PNG loading 
     int imgFlags = IMG_INIT_PNG; 
     if (!(IMG_Init(imgFlags) & imgFlags)) 
     { 
      printf("SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError()); 
      success = false; 
     } 

     //Initialize SDL_ttf 
     if (TTF_Init() == -1) 
     { 
      printf("SSDL_ttf could not initialize! SDL_ttf Error: %s\n", TTF_GetError()); 
      success = false; 
     } 
    } 
    return success; 
} 

也许我有内存泄漏或悬空指针,但我找不到在哪里的错误是。如果有人能找到我错在哪里,我将非常高兴。如果您需要任何额外的代码段

+3

您是否尝试过使用调试器并单步执行代码以查看程序在哪一行中断? –

+0

您能向我们展示您的SDL初始化代码吗? – developerbmw

+0

@MigaraLiyanagamage调试器以完全随机的代码片段显示,以前完美的工作,这让我想到,新的功能混淆了内存。 – gavriktonio

回答

0

显然,我提供的代码中没有错误。我错误地初始化了SDL_mixer。我装音响这样 if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0),但我提供的wav文件的采样率不MIX_DEFAULT_FORMAT,这是22050. 无论如何,感谢大家,谁试图帮助我与我的代码。在最短的时间使用stackoverflow是一个愉快的经历。

0

除非你有一个不变的地方,保证ObstacleSet从来没有在一个空的障碍调用任何列出有一个潜在的问题收件箱。

此代码是未定义行为空单

float ObstacleSet::getX(int number) 
{ 
    unsigned N = number; 
    std::list<Obstacle>::iterator i = Obstacles.begin(); 
    if (Obstacles.size() > N) 
    { 
     std::advance(i, N); 
    } 
    return i->xPos; 
} 

在试图修复它

float ObstacleSet::getX(int number) 
{ 
    unsigned N = number; 
    std::list<Obstacle>::iterator i = Obstacles.begin(); 
    if (Obstacles.size() > N) 
    { 
     std::advance(i, N); 
    } 
    if (i != Obstacles.end()) 
     return i->xPos; 
    // handle empty 
    return ERRORPOS; // or throw or assert or ... 
} 

同样的,访问列表中的所有其他职能。

+0

@Diversity,要么我需要更多的睡眠,否则这个评论不适合我。 – Surt

+0

@Surf用一个答案替换了评论 – Diversity

0

一些问题,我看到的代码:

  1. ObstacleSet::move()添加五大障碍到列表中。它看起来像列表可以无限增长,导致内存溢出。

  2. 您不检查ObstacleseraseObstacle()getX()中是否为空,也可能是其他未显示的功能。