以下程序每次启动时都会以状态3结束。
#include "amr-0-1.h"
#include "SDL_sys.c"
int screen_w=351, screen_h=234;
int ss_w=screen_w*(5/9), ss_h=screen_h*(11/19);
int m_w=screen_w*(7/27), m_h=screen_h*(175/234);
int g_w=screen_w*(100/351), g_h=screen_h*(2/9);
int mo_w=screen_w*(29/117), mo_h=screen_h*(1/13);
int ss_mo_w=screen_w*(17/117), ss_mo_h=screen_h*(4/117);
int p_d=32, border=2;
SDL_Surface *screen = NULL; //Fenetre principale
SDL_Surface *m = NULL; //Surface du menu
SDL_Surface *mo = NULL; //Surface d'une option menu
SDL_Surface *ss = NULL; //Surface de la zone d'écran secondaire
SDL_Surface *ss_mo = NULL; //Surface d'une option du sous-menu
SDL_Surface *p = NULL; //Surface destinée à accueillir l'image utilisateur
SDL_Rect c_m;
SDL_Rect c_mo;
SDL_Rect c_ss;
SDL_Rect c_ss_mo;
SDL_Rect c_p;
SDL_Rect c_screen;
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
fprintf(stderr, "Erreur d'initialisation de la SDL");
exit(EXIT_FAILURE);
}
SGI_Init(1, screen, 351, 234, NULL, 0, 0, &c_screen); //Écran principal
SGI_Init(0, m, m_w, m_h, screen, 39, 58, &c_m); //Menu
SGI_Init(0, ss, ss_w, ss_h, screen, 156, 78, &c_ss); //Surface d'écran secondaire
pause();
SDL_Quit();
return EXIT_SUCCESS;
}
根据我的研究,状态3代表SegFault'所以它是一个(或多个)SDL'的分配问题。表面。以下是我分配表面的方法:
#include "amr-0-1.h"
void pause()
{
int continuer = 1;
SDL_Event event;
while (continuer)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
}
}
}
int SGI_Init(int command, SDL_Surface *child, int child_w, int child_h, SDL_Surface *mother, int x, int y, SDL_Rect* cursor)
{
if(command)
{
child = SDL_SetVideoMode(child_w, child_h, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
return 1;
}
else if(!command)
{
child = SDL_CreateRGBSurface(SDL_HWSURFACE, child_w, child_h, 32, 0,0,0,0);
SDL_FillRect(child, cursor, SDL_MapRGB(mother->format,255,255,255));
cursor->x=x;
cursor->y=y;
SDL_BlitSurface(child, NULL, mother, cursor);
SDL_Flip(mother);
return 1;
}
else
{
return 0;
}
}
标题amr-0-1.h:
#include <stdlib.h>
#include <stdio.h>
#include <SDL.h>
void pause();
int SGI_Init(int command, SDL_Surface *child, int child_w, int child_h, SDL_Surface *mother, int x, int y, SDL_Rect* cursor);
我无法找到分配错误的原因 我使用SDL 1.2和CodeBlocks 17.12,我也是一个菜鸟,我是法国人,所以请耐心等待我慢!
答案 0 :(得分:1)
即时SEGFAULT可能是由
引起的SDL_FillRect(child, cursor, SDL_MapRGB(mother->format,255,255,255));
背后的原因在keltar的评论中得到了回答:
在这一行:
SGI_Init(1, screen, 351, 234, NULL, 0, 0, &c_screen);
您传入screen
以初始化它。
这里发生的是screen
的值被复制到 local 变量child
中。
然后修改child
,但这发生在screen
的副本,screen
本身保持不变。
您可能会对screen
是指针这一事实感到困惑。
但是,您想要修改指针,因此您需要一个指向指针的指针,如下所示:
int SGI_Init(int command, SDL_Surface **child, int child_w, int child_h, SDL_Surface *mother, int x, int y, SDL_Rect* cursor)
{
if(command)
{
*child = SDL_SetVideoMode(child_w, child_h, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
return 1;
}
else if(!command)
{
*child = SDL_CreateRGBSurface(SDL_HWSURFACE, child_w, child_h, 32, 0,0,0,0);
SDL_FillRect(*child, cursor, SDL_MapRGB(mother->format,255,255,255));
cursor->x=x;
cursor->y=y;
SDL_BlitSurface(*child, NULL, mother, cursor);
SDL_Flip(mother);
return 1;
}
else
{
return 0;
}
}
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
fprintf(stderr, "Erreur d'initialisation de la SDL");
exit(EXIT_FAILURE);
}
SGI_Init(1, &screen, 351, 234, NULL, 0, 0, &c_screen); //Écran principal
printf("%p\n", screen);
SGI_Init(0, &m, m_w, m_h, screen, 39, 58, &c_m); //Menu
SGI_Init(0, &ss, ss_w, ss_h, screen, 156, 78, &c_ss); //Surface d'écran secondaire
pause();
SDL_Quit();
return EXIT_SUCCESS;
}
但为什么不直接返回新的SDL_Surface
:
SDL_Surface* SGI_Init(int command, int child_w, int child_h, SDL_Surface *mother, int x, int y, SDL_Rect* cursor)
{
if(command)
{
return SDL_SetVideoMode(child_w, child_h, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
}
else if(!command)
{
SDL_Surface* child = SDL_CreateRGBSurface(SDL_HWSURFACE, child_w, child_h, 32, 0,0,0,0);
SDL_FillRect(child, cursor, SDL_MapRGB(mother->format,255,255,255));
cursor->x=x;
cursor->y=y;
SDL_BlitSurface(child, NULL, mother, cursor);
SDL_Flip(mother);
return child;
}
else
{
return 0;
}
}
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
fprintf(stderr, "Erreur d'initialisation de la SDL");
exit(EXIT_FAILURE);
}
screen = SGI_Init(1, 351, 234, NULL, 0, 0, &c_screen); //Écran principal
printf("%p\n", screen);
m = SGI_Init(0, m_w, m_h, screen, 39, 58, &c_m); //Menu
ss = SGI_Init(0, ss_w, ss_h, screen, 156, 78, &c_ss); //Surface d'écran secondaire
pause();
SDL_Quit();
return EXIT_SUCCESS;
}
您的代码中有一些可能导致未定义行为的内容,例如
SDL_Rect c_m;
SDL_Rect c_mo;
SDL_Rect c_ss;
...
声明变量,但是你永远不会初始化它们,你只需将它们作为参数传递给函数。如果在初始化之前曾经读过其中一个,则会造成未定义的行为。
即便如此,那里有很多代码味道,command
参数显而易见的是最引人注目的一个:你的SDI_Init
函数做了两件完全不同的事情。您应该尝试坚持single responsibility principle并将功能分成两个功能 - 每个任务一个。如果您想坚持自己的设计,至少可以使用适当的enum
command
...