代码之家  ›  专栏  ›  技术社区  ›  user151768

c函数在未被调用的情况下重复执行,导致segfault

  •  -1
  • user151768  · 技术社区  · 7 年前

    我一直在学习LazyFoo的SDL2教程,并对代码进行了一些修改,以便在Linux上将其编译为C代码(我是一名C程序员,对C++知之甚少)。在 second tutorial 他将代码分为四个函数: init() 处理所有初始化, loadMedia() 加载图像, close() 最后释放所有内存 main() .

    我的问题是 初始化() 函数(紧随其后 SDL_Init(SDL_INIT_VIDEO) 被称为), 关闭() 在执行 初始化() . 关闭() 然后在程序出现故障之前再运行几次。

    我对代码的修改如下:

    • 改变 #include <SDL.h> #include <SDL2/SDL.h>
    • include <stdbool.h> ,按照C的要求
    • 将文件扩展名更改为。c来自。cpp公司
    • 在中为程序的渲染部分添加while循环 main() :

      SDL_Event event;
      int quit = false;
      while( !quit ) {
          SDL_WaitEvent( &event );
          if( event.type == SDL_QUIT ) {
              quit = true;
          }
          //Apply the image
          SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );
          //Update the surface
          SDL_UpdateWindowSurface( gWindow );
      }
      

      这是为了修复我在第一个教程中遇到的一个问题,其中没有任何内容被绘制到窗口

    • 管线的拆除 SDL_Delay( 2000 ); 因为渲染循环不需要它
    • 更改的路径。bmp文件来自 02_getting_an_image_on_the_screen/hello_.bmp hello.bmp 因为源和图像位于同一文件夹中

    我发现,即使我删除对的调用,也会发生错误 关闭() ,但如果完全删除该函数,则运行良好。如果我将文件扩展名保留为,它也可以正常运行。cpp,尽管据我所知,没有任何代码使用C++特定的特性。可能值得注意的是,a窗口已成功创建,但从未向其绘制任何内容。我真的不知道这一切的原因是什么。

    我在Debian Stretch安装上使用GCC V6.3.0编译了代码。原始来源可在上面链接的页面下载。我的修改版本如下。

    /*This source code copyrighted by Lazy Foo' Productions (2004-2015)
    and may not be redistributed without written permission.*/
    
    //Using SDL and standard IO
    #include <SDL2/SDL.h>
    #include <stdio.h>
    #include <stdbool.h>
    
    //Screen dimension constants
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    
    //Starts up SDL and creates window
    bool init();
    
    //Loads media
    bool loadMedia();
    
    //Frees media and shuts down SDL
    void close();
    
    //The window we'll be rendering to
    SDL_Window* gWindow = NULL;
    
    //The surface contained by the window
    SDL_Surface* gScreenSurface = NULL;
    
    //The image we will load and show on the screen
    SDL_Surface* gHelloWorld = NULL;
    
    bool init()
    {
        //Initialization flag
        bool success = true;
    
        //Initialize SDL
        if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
        {
            printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
            success = false;
        }
        else
        {
            //Create window
            gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 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
            {
                //Get window surface
                gScreenSurface = SDL_GetWindowSurface( gWindow );
            }
        }
    
        return success;
    }
    
    bool loadMedia()
    {
        //Loading success flag
        bool success = true;
    
        //Load splash image
        gHelloWorld = SDL_LoadBMP( "hello_world.bmp" );
        if( gHelloWorld == NULL )
        {
            printf( "Unable to load image %s! SDL Error: %s\n", "hello_world.bmp", SDL_GetError() );
            success = false;
        }
    
        return success;
    }
    
    void close()
    {
        //Deallocate surface
        SDL_FreeSurface( gHelloWorld );
        gHelloWorld = NULL;
    
        //Destroy window
        SDL_DestroyWindow( gWindow );
        gWindow = NULL;
    
        //Quit SDL subsystems
        SDL_Quit();
    }
    
    int main( int argc, char* args[] )
    {
        //Start up SDL and create window
        if( !init() )
        {
            printf( "Failed to initialize!\n" );
        }
        else
        {
            //Load media
            if( !loadMedia() )
            {
                printf( "Failed to load media!\n" );
            }
            else
            {
                SDL_Event event;
                int quit = false;
                while( !quit ) {
                    SDL_WaitEvent( &event );
                    if( event.type == SDL_QUIT ) {
                        quit = true;
                    }
                    //Apply the image
                    SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );
    
                    //Update the surface
                    SDL_UpdateWindowSurface( gWindow );
                }
            }
        }
    
        //Free resources and close SDL
        close();
    
        return 0;
    }
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   Stack Exchange Supports Israel    7 年前

    close 是一个操作系统函数,用于关闭文件句柄(打开的文件、套接字或任何内容)。

    您已经定义了自己的函数 ,并且您自己的函数优先于库函数。每当有东西想要关闭文件句柄时,它都会调用 作用(而且文件句柄不会关闭,因为 未调用函数)。