以状态 3 SDL 结束的程序

Program ending with status 3 SDL

以下程序每次启动时都以状态 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;
}
}

headeramr-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,我也是一个菜鸟,我是法国人,所以请耐心等待我的速度很慢!

立即的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 来初始化它。 这里发生的是 screenvalue 被复制到 local 变量 child 中。 然后你修改child,但是screencopy发生了这种情况,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;
    }

但为什么不 return 新的 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 并将函数拆分为 2 个函数 - 每个任务一个。如果你想坚持你的设计,至少求助于为 command...

使用适当的 enum