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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6811882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:42:50  来源:igfitidea点击:

0xC0000005: Access violation reading location 0x00000008

c++

提问by JasonM.

I have been struggling with this for a while and was wondering if anyone could help. I am trying to make a particle sample using C++ and SDL1.3 and I have had great success up until this point. The program compiles and the screen opens and nothing happens. When I run the debugger I get this error:

我已经为此苦苦挣扎了一段时间,想知道是否有人可以提供帮助。我正在尝试使用 C++ 和 SDL1.3 制作粒子样本,到目前为止我已经取得了巨大的成功。程序编译,屏幕打开,什么也没有发生。当我运行调试器时,出现此错误:

Unhandled exception at 0x0102414a in SDL 1.3 Space.exe: 0xC0000005: Access violation reading location 0x00000008. The program '[7272] SDL 1.3 Space.exe: Native' has exited with code -1073741819 (0xc0000005).

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

and it points to this piece of the code:

它指向这段代码:

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

It would be greatly appreciated if someone would be so kind as to help me and /or point me in the right direction.

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

This is the entire program:

这是整个程序:

#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;
}

回答by Necrolis

Access violations mean you are dereferencing null pointers(or pointers to memory you don't have access to), so this would mean (assuming the debugger synced with the source correctly) that SDL_GetVideoSurfaceis returning null, so you'll probably wanna throw a few checks in isDead. Secondly, its probably a good idea to store the w/h of the surface minus 1 in your class at during the creation of the surface, should mean a little less computational overhead along with shorter code.

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