c函数在没有被调用的情况下重复执行,导致段错误
c function executes repeatedly without being called, causes segfault
我一直在关注 LazyFoo 的 SDL2 教程并稍微修改代码,以便我可以将其编译为 Linux 上的 C 代码(我是一名 C 程序员,不太了解 C++)。在 second tutorial 中,他将代码分成四个函数:init()
处理所有初始化,loadMedia()
加载图像,close()
释放所有内存结束,以及main()
。
我的问题是 init()
函数的中途(就在 SDL_Init(SDL_INIT_VIDEO)
被调用之后),close()
在执行 [=12] 的其余部分之前被重复调用(181 次) =]. close()
然后在程序出现段错误之前再运行几次。
我对代码的修改如下:
- 将
#include <SDL.h>
更改为 #include <SDL2/SDL.h>
include <stdbool.h>
,按C 的要求
- 将文件扩展名从 .cpp 更改为 .c
在main()
中为程序的渲染部分添加了一个while循环:
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 );
}
这是为了解决我在第一个教程中遇到的问题,即 window
没有绘制任何内容
- 删除行
SDL_Delay( 2000 );
因为渲染循环不需要它
- 将 .bmp 文件的路径从
02_getting_an_image_on_the_screen/hello_.bmp
更改为 hello.bmp
,因为源和图像位于同一文件夹中
我发现即使我删除对 close()
的调用也会出现错误,但如果我完全删除该函数则运行正常。如果我将文件扩展名保留为 .cpp,它也可以正常运行,尽管据我所知 none 代码使用了 C++ 特定功能。可能值得注意的是,a window 已成功创建,但从未绘制任何内容。我真的不知道这一切的原因是什么。
我在 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;
}
close
是关闭文件句柄(打开的文件、套接字或任何东西)的操作系统函数。
您已经定义了自己的函数 close
,并且您自己的函数优先于库函数。每次要关闭文件句柄时,它都会调用您的 close
函数。 (而且文件句柄也没有关闭,因为真正的 close
函数没有被调用)。
我一直在关注 LazyFoo 的 SDL2 教程并稍微修改代码,以便我可以将其编译为 Linux 上的 C 代码(我是一名 C 程序员,不太了解 C++)。在 second tutorial 中,他将代码分成四个函数:init()
处理所有初始化,loadMedia()
加载图像,close()
释放所有内存结束,以及main()
。
我的问题是 init()
函数的中途(就在 SDL_Init(SDL_INIT_VIDEO)
被调用之后),close()
在执行 [=12] 的其余部分之前被重复调用(181 次) =]. close()
然后在程序出现段错误之前再运行几次。
我对代码的修改如下:
- 将
#include <SDL.h>
更改为#include <SDL2/SDL.h>
include <stdbool.h>
,按C 的要求
- 将文件扩展名从 .cpp 更改为 .c
在
main()
中为程序的渲染部分添加了一个while循环: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 ); }
这是为了解决我在第一个教程中遇到的问题,即 window
没有绘制任何内容
- 删除行
SDL_Delay( 2000 );
因为渲染循环不需要它 - 将 .bmp 文件的路径从
02_getting_an_image_on_the_screen/hello_.bmp
更改为hello.bmp
,因为源和图像位于同一文件夹中
我发现即使我删除对 close()
的调用也会出现错误,但如果我完全删除该函数则运行正常。如果我将文件扩展名保留为 .cpp,它也可以正常运行,尽管据我所知 none 代码使用了 C++ 特定功能。可能值得注意的是,a window 已成功创建,但从未绘制任何内容。我真的不知道这一切的原因是什么。
我在 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;
}
close
是关闭文件句柄(打开的文件、套接字或任何东西)的操作系统函数。
您已经定义了自己的函数 close
,并且您自己的函数优先于库函数。每次要关闭文件句柄时,它都会调用您的 close
函数。 (而且文件句柄也没有关闭,因为真正的 close
函数没有被调用)。