Ошибка сегментации на функции - PullRequest
0 голосов
/ 23 апреля 2011

Я изучаю, как использовать библиотеку SDL для графического программирования, и у меня возникает ошибка сегментации следующего кода:

int situador(SDL_Surface * dib,struct sit_per per)
{

    SDL_Rect pos;
    struct sit_per * est;
    est=&per;


    while(est)
    {
        pos.x = est->ac->x;
        pos.y = est->ac->y;
        pos.w = est->ac->img[est->ac->dir]->w;
        pos.h = est->ac->img[est->ac->dir]->h;
        SDL_BlitSurface(est->ac->img[est->ac->dir], NULL, dib, &pos);
        est=est->si;
    }


    return 0;
}

Переменная dib поступает из этой функции:

SDL_Surface * draw = SDL_CreateRGBSurface(SDL_SWSURFACE, ANCHO, ALTO, 24,rmask, gmask,bmask, amask);

Структура sit_per следующая:

struct sit_per
{
    struct personaje * ac;
    struct sit_per * si;
};

struct personaje
{
    char des[50];
    SDL_Surface * img[8];
    int dir;
    int x;
    int y;
};

И массив img был заполнен следующей функцией:

struct personaje * creador(char * cad)
{
    int x;
    struct personaje * per;

    per=(struct personaje *)malloc(sizeof(struct personaje));
    strcpy(per->des,cad);

    per->img[0] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/0.bmp");
    per->img[1] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/1.bmp");
    per->img[2] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/2.bmp");
    per->img[3] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/3.bmp");
    per->img[4] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/4.bmp");
    per->img[5] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/5.bmp");
    per->img[6] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/6.bmp");
    per->img[7] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/7.bmp");
    per->img[8] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/8.bmp");

    for(x=0;x<9;x++)
        if(!per->img[x])
            x=10;
    if(x==10)
        return NULL;
    else
        return per;
}

Я уверен, что маршрут к изображениям хорошонаписал, и я могу сказать, что координаты X и Y тоже хорошо.

Я буду признателен за любые предложения, спасибо заранее.

Ответы [ 2 ]

4 голосов
/ 23 апреля 2011

Ваш код загружает 9 указателей изображений в массив из 8 элементов.

Это не рецепт счастья.

1 голос
/ 23 апреля 2011

В вашем коде есть несколько странностей.

Во-первых,

int situador(SDL_Surface * dib,struct sit_per per)
{
    SDL_Rect pos;
    struct sit_per * est;
    est=&per;

пусть это будет

int situador(SDL_Surface * dib,struct sit_per *per)
{
    SDL_Rect pos;
    struct sit_per * est = per; // assignment can be made later

просто стиль, избегая слишком большого объема данных и копирования настек.

Использование цикла for также может быть опцией;

  for(est = per; est != NULL; est = est->si)

Если функция всегда возвращает фиксированное значение, вы можете заставить ее ничего не возвращать ...;Итак, void situador(...) вместо int situador(...).

Функция creador загружает 9 изображений, когда требуется только 8 (по одному на каждое направление, я полагаю), это источник для segfault;не жестко кодировать (абсолютные) пути к файлам, как сказано выше.

Чтобы выйти из цикла for, используйте ключевое слово break , избегайте в общем случае изменения переменной цикла (если только вы неесть веская причина, и здесь я не вижу ни одной).Опять же, цикл for для 9 изображений, где у вас есть место только для 8 в вашем массиве.Если вам нужно 9-е изображение, вы должны написать SDL_Surface * img[9];.Это может сбивать с толку, но когда вы объявляете массив, число в скобках - это количество элементов, а при доступе индекс начинается с 0, так что последний элемент имеет индекс N-1.

весь финальный кусок может стать

for(x = 0; x < NUM_OF_ELEMENT; x++)
    if(!per->img[x])
        break;
if (x < NUM_OF_ELEMENT)
{
    int y;
    for(y = 0; y < x; y++)
       SDL_func_to_free_loaded_images(per->img[y]);
    free(per);
    return NULL;
}
else
    return per;

обычно лучше использовать именованные константы, а не число;например,

#define  NUM_OF_ELEMENT 8
#define  NUM_OF_DES  50

и т. д.

   struct personaje
   {
      char des[NUM_OF_DES];
      SDL_Surface * img[NUM_OF_ELEMENT];
      int dir;
      int x;
      int y;
   };

и т. д. (конечно, вы выберете другое имя, например, NUM_OF_DIRS или NUM_OF_IMAGES или любую другую предпочитаемую вами форму на вашем языке)

...