无法解决SDL中的分段错误(核心转储)

时间:2016-04-21 10:16:29

标签: c segmentation-fault sdl

我无法找到分段错误发生的位置,无论是在使用gdb还是在下面的代码中放入许多printfs之后,依旧是:

  #include <stdio.h>
  #include <stdlib.h>
  #include <math.h>
  #include "../GCGraLib2/GCGraLib2.h"

  #define DIM 100

这里我们计算一个点与数组中一组点之间的距离

  float *dist2(int px,int py,int x[],int y[])
  {
  float min,d;int i=1;min=pow(abs(px-x[0]),2)+pow(abs(py-y[0]),2);;
  int nearestp;static float output[2];
    while (i<=DIM) {
          d=pow(abs(px-x[i]),2)+pow(abs(py-y[i]),2);
    if (d<min){min=d;}
        i++;
  }
    nearestp=i-1;
    output[0]=d;output[1]=nearestp;
  return output;
}

这是重绘下面描述的多边形

  void redraw(int n, int x[], int y[],SDL_Renderer *ren)
  {
  int i;
  GC_FillCircle(ren,x[0],y[0],3);
    for (i=1; i<=n; i++)
    {
      SDL_RenderDrawLine(ren, x[i-1], y[i-1], x[i], y[i]);
    GC_FillCircle(ren,x[i],y[i],3);
    }
  }

将过滤器用于事件队列

  int isMouseEvent(int * motioncounter,SDL_Event * event) {
    *motioncounter=*motioncounter+1;
  if (*motioncounter<=5) {
          return 0;}
      else {
          *motioncounter=0;
          return 1;
      }
  }

这是通过贝塞尔曲线

对一组点的插值
  void bezier(SDL_Renderer *ren, int x[], int y[], int n)
  {
    int i,k,tempo,indice;
    float t = 0;
      float xx[DIM],yy[DIM];
      float bx[DIM],by[DIM];
      printf("BEZIER\n");
      // coefficienti da usare nell'algoritmo
      for (tempo=0;tempo<=99;tempo++)
      {
          for (indice=0;indice<=n;indice++)
          {
              xx[indice]=x[indice];
          }
          for (indice=0;indice<=n;indice++)
          {
              yy[indice]=y[indice];
          }
          for (k=1;k<n;k++)
          {
              for (i=0;i<n-k;i++)
              {
                  // trovo coordinante della curva al tempo t
                  xx[i]=(1-t)*xx[i]+t*xx[i+1];
                  yy[i]=(1-t)*yy[i]+t*yy[i+1];
              }             
          }
          //coordinate del punto
          bx[tempo]=xx[0];
          by[tempo]=yy[0];
          t=t+0.01;
      }
      // aggiornare ren con coordinate curva
      // rendo tutto le schermo nero
      SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
  SDL_RenderClear(ren);
      // ristampare i punti
      for (i=0;i<n;i++)
      {
          SDL_SetRenderDrawColor(ren, 255, 255, 0, 255);
          GC_FillCircle(ren,x[i],y[i],3);
      }

      for (tempo=0;tempo<=98;tempo++)
      {
          SDL_RenderDrawLine(ren, bx[tempo], by[tempo], bx[tempo+1], by[tempo+1]);
      }

  }

这里我们控制I / O的通量

  int main(void) 
  {
  SDL_Window *win;
  SDL_Renderer *ren;
  SDL_Event event;
  int vxmax,vymax;
  int esc=1,i,j,n=0;SDL_EventFilter prune=0;
  int x[DIM],y[DIM];int readytomove=0;
  float *DIST;float dist;int nearestp;
  Uint32 windowID;int motioncounter=0;

    if(SDL_Init(SDL_INIT_VIDEO)<0)
    {
      fprintf(stderr,"Couldn't init video: %s\n",SDL_GetError());
      return(1);
    }

    vxmax=300;
    vymax=300;

  win= SDL_CreateWindow("Inter_Polygon", 100, 100, vxmax, vymax, 
                           SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
  if(win==NULL){
      fprintf(stderr,"SDL_CreateWindow Error: %s\n",SDL_GetError());
      SDL_Quit();
      return 1;
  }

  ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
  if (ren == NULL){
      SDL_DestroyWindow(win);
      fprintf(stderr,"SDL_CreateRenderer Error: %s\n",SDL_GetError());
      SDL_Quit();
    return 1;
  }

  SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
  SDL_RenderClear(ren);
  SDL_SetRenderDrawColor(ren, 255, 0, 50, 255);
   SDL_RenderPresent(ren);

这里我们通过点击一些点来绘制多边形。退出按Esc键。

  while(esc)
  {
      if (SDL_PollEvent(&event))
          prune=(SDL_EventFilter) isMouseEvent(& motioncounter,&event);
          SDL_SetEventFilter(prune,& motioncounter);
      switch(event.type)
      {
      case SDL_MOUSEBUTTONDOWN:
          if(event.button.button==1)
          {
                  DIST = dist2(event.button.x,event.button.y,x,y);nearestp=DIST[1];dist=DIST[0];
                  if (dist >= 6.5) {
                          readytomove=0;
              x[n]=event.button.x;
              y[n]=event.button.y;
              GC_FillCircle(ren,x[n],y[n],3);
              if(n>1) {
                            printf("CALL TO BEZIER: n=%i\n",n); 
  //            SDL_RenderDrawLine(ren, x[n-1], y[n-1], x[n], y[n]);
                            bezier(ren,x,y,n);
                    n++;
                }
                    else{readytomove=1;}
                    }
                }
             break;
         case SDL_MOUSEMOTION:
          if(event.button.button==1)
          {
                DIST = dist2(event.button.x,event.button.y,x,y);nearestp=DIST[1];dist=DIST[0];
                if (readytomove)
              {
                    x[nearestp]=event.button.x;
                    y[nearestp]=event.button.y;
                    GC_FillCircle(ren,x[1],y[1],3);
                  if(n>0){
                      bezier(ren,x,y,n);
                            n++;
                      }
                  }
              }
           SDL_RenderPresent(ren);
         break;
         case SDL_KEYDOWN:
         if(event.key.keysym.sym == SDLK_ESCAPE)
           esc=0;
         break;
         case SDL_WINDOWEVENT:
             windowID = SDL_GetWindowID(win);
             if (event.window.windowID == windowID)  {
                switch (event.window.event)  {
             case SDL_WINDOWEVENT_SIZE_CHANGED:  {
               vxmax = event.window.data1;
               vymax = event.window.data2;
  //                     printf("vxmax= %d \n vymax= %d \n", vxmax,vymax);
               SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);     
                         SDL_RenderClear(ren);
               SDL_SetRenderDrawColor(ren, 255, 0, 50, 255);
                       redraw(n-1,x,y,ren);
                       SDL_RenderPresent(ren);
                     break;
                   }
               }
            }
         break;

            }
    }

    SDL_Quit();
    return(0);
  }

编译使用

gcc -DDEBUG -c -Wall binter_polygon2ren.c | gcc binter_polygon2ren.o ../GCGraLib2/GCGraLib2.o -L/usr/X11R6/lib -lX11 -lSDL2 -lSDL2_ttf -lSDL2_image -lm -o binter_polygon2re

感谢。

1 个答案:

答案 0 :(得分:1)

我注意到我们无法检查完整的控制流程,即我无法查看每个函数的调用位置。但我很确定您的数组索引中存在错误。

C中大小为 N 的所有数组都有成员 0..N-1 。我看到你在大小为main的{​​{1}}中分配数组,但稍后(例如在DIM中)我看到数组从1到DIM被索引,这导致了一个越界的情况和你覆盖堆栈上的东西。

dist2中,我看到了:

redraw

我注意到它会越界。这应该是:

for (i=1; i<=n; i++)
{
   SDL_RenderDrawLine(ren, x[i-1], y[i-1], x[i], y[i]);

我建议你彻底检查所有索引和数组边界。