0xC0000005:访问冲突读取位置0x00000008

时间:2011-07-25 04:46:51

标签: c++

我一直在努力解决这个问题,并且想知道是否有人可以提供帮助。我正在尝试使用C ++和SDL1.3制作粒子样本,直到这一点我都取得了很大的成功。程序编译,屏幕打开,没有任何反应。当我运行调试器时,我收到此错误:

SDL 1.3 Space.exe中0x0102414a处的未处理异常:0xC0000005:访问冲突读取位置0x00000008。 程序'[7272] SDL 1.3 Space.exe:Native'已退出,代码为-1073741819(0xc0000005)。

它指向这段代码:

bool particle::isDead()
{
    return (SDL_GetTicks() >= endTime || x == 0 || y == 0 || x == SDL_GetVideoSurface()->w -1 || y == SDL_GetVideoSurface()->h - 1);
}

如果有人愿意帮助我和/或指出正确的方向,我们将不胜感激。

这是整个计划:

#include "SDL.h"
#include "common.h"
#include <stdio.h>
#include <string>
#include <cstdlib>
#include <vector>
#include <ctime>

/*static SDL_Texture *background = 0; //background
  SDL_Renderer *renderer;

void render()
{   
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
    SDL_RenderClear(renderer);
    SDL_RenderCopy(renderer, background, NULL, NULL); //Display background
    SDL_RenderPresent(renderer);
    endFrame = SDL_GetTicks();
};*/ 

class particle
{
    float x, y, xvel, yvel;
    Uint32 endTime;
    Uint8 color;

    public:
        particle( float X, float Y, float Xvel, float Yvel, int life, Uint8 Color  );
        void move();
        void show();
        bool isDead();
};

particle::particle( float X, float Y, float Xvel, float Yvel, int life, Uint8 Color )
{
    x = X;
    y = Y;
    xvel = Xvel;
    yvel = Yvel;
    endTime = SDL_GetTicks() + life;
    color = Color;
}

void particle::move()
{
    x += xvel;
    y += yvel;

    if ( x < 0 )
        x = 0;

    if ( y < 0 )
        y = 0;

    if ( x > SDL_GetVideoSurface() -> w)
        x = SDL_GetVideoSurface()  -> w - 1;

    if ( y > SDL_GetVideoSurface() -> h)
        y = SDL_GetVideoSurface()  -> h -1;
}

void particle::show()
{
    Uint8* pixels = (Uint8*) SDL_GetVideoSurface()->pixels;
    Uint8* pixel = pixels + (int) y * SDL_GetVideoSurface()->pitch + (int) x;
    *pixel = color;
}

bool particle::isDead()
{
    return (SDL_GetTicks() >= endTime || x == 0 || y == 0 || x == SDL_GetVideoSurface()->w -1 || y == SDL_GetVideoSurface()->h - 1);
}

class particleEngine
{
    std::vector <particle*> particles;
    int x, y, maxparticle;

    public:
        particleEngine( int maxpart, int X, int Y );
        ~particleEngine();
        void refresh();
};

particleEngine::particleEngine( int maxpart, int X, int Y )
{
    x = X;
    y = Y;
    maxparticle = maxpart;
    for ( int i = 0; i < maxparticle; i++ )
        particles.push_back (new particle( x + rand()%6-3, y + rand()%6-3, rand()%10 + (float)rand()/(float)RAND_MAX - 5, rand()%10 + (float)rand()/(float)RAND_MAX - 5, 500 + rand()%1000, 0));
}

particleEngine::~particleEngine()
{
    for ( int i = 0; i < maxparticle; i++)
        delete particles[i];
}

void particleEngine::refresh()
{
    for ( int i = 0; i < maxparticle; i++)
    {
        if ( particles[i]->isDead())
        {
            delete particles[i];
            particles[i] = new particle( x + rand()%6-3, y + rand()%6-3, rand()%10 + (float)rand()/(float)RAND_MAX - 5, rand()%10 + (float)rand()/(float)RAND_MAX - 5, 500 + rand()%1000, 0);
        }
        else
        {
            particles[i]->move();
            particles[i]->show();
        }
    }
}

int main( int argc, char* argv[] )
{
    bool running = true;
    const int FPS = 30;
    Uint32 startFrame;
    srand (time(0));
    particleEngine ps(1000, SCREEN_WIDTH/2, SCREEN_HEIGHT/2);

    SDL_Window *window;         /* main window */
    SDL_Renderer *renderer;

    if (SDL_Init(SDL_INIT_EVERYTHING)!= 0) 
    {
        printf("Could not initialize SDL");
    }

    window = SDL_CreateWindow("SDL 1.3 Particles", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT,
                            SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

    // Body of the program goes here.
    while (running)
    {
        startFrame = SDL_GetTicks();
        SDL_Event event;
        //render();
        //While there's events to handle
        while( SDL_PollEvent( &event ) )
        {
            //If the user has Xed out the window
            if (event.type == SDL_QUIT) 
        {
            running = false;
        }
    }

    //SDL_FillRect(renderer, &renderer->clip_rect, SDL_MapRGB(renderer->format, 0x00,0x00, 0x00));

    ps.refresh();
    //SDL_RenderCopy(renderer, 0, 0, 0);
    SDL_RenderPresent(renderer);
    //SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    //SDL_RenderClear(renderer);

    if (1000/FPS>SDL_GetTicks()-startFrame)
        SDL_Delay(1000/FPS-(SDL_GetTicks()-startFrame));

}
  SDL_Quit();
  return 0;
}

1 个答案:

答案 0 :(得分:3)

访问冲突意味着您正在取消引用空指针(或指向您无权访问的内存的指针),因此这意味着(假设调试器与源正确同步)SDL_GetVideoSurface返回null,因此你可能想在isDead中扔一些支票。其次,在创建表面期间,在类中存储表面的w / h减去1可能是一个好主意,应该意味着更少的计算开销和更短的代码。