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

0xC0000005: Access violation reading location 0x00000008

本文关键字:位置 0x00000008 读取 访问冲突 0xC0000005      更新时间:2023-10-16

我已经为此挣扎了一段时间,想知道是否有人可以帮助。我正在尝试使用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;
}

访问违规意味着您正在解引用空指针(或指向您无法访问的内存的指针),因此这意味着(假设调试器与源正确同步)SDL_GetVideoSurface返回null,因此您可能想要在isDead中抛出一些检查。其次,在创建表面时,将表面的w/h - 1存储在类中可能是个好主意,这意味着计算开销更少,代码更短。