2016-04-21 6 views
0

Ich kann nicht in der Lage sein zu finden, wo die Segmentation fault Fehler auftreten, lösen weder nach gdb oder viele printfs im folgenden Code setzen, die in Ordnung ist:Kann nicht Segmentation fault (core dumped) in SDL

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

    #define DIM 100 

Hier berechnen wir einen Abstand zwischen einem Punkt und einem Satz von Punkt in einem Array

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; 
} 

Hier wird der polygonal Neuzeichnen descripted unten

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); 
    } 
    } 

Verwendung von Filter für die Warteschlange von Ereignissen ist

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

Hier ist die Interpolation einer Reihe von Punkten durch Bezierkurve

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]); 
     } 

    } 

Hier haben wir den Fluss von I/O-Steuerung

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); 

Hier zeichnen wir einen Polygon durch Klicken auf einige Punkte. Um zu beenden, drücken Sie die Esc-Taste.

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); 
    } 

Zur Verwendung

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 

Dank kompilieren.

+1

Zumindest wäre es hilfreich zu wissen, was GDB * Ihnen tatsächlich sagen kann * Wenn der Stack-Trace komisch aussieht, besteht eine hohe Wahrscheinlichkeit, dass Sie den Stack beschädigt haben. – tofro

+0

Vielleicht trennen Sie das Programm in Teile. Beginnen Sie mit dem Versuch, etwas Einfaches zu tun, und fügen Sie dann Teile hinzu, um zu dem zu gelangen, was Sie hier versuchen. –

+1

In welcher Zeile tritt der Segfault auf? –

Antwort

1

Ich bemerke, dass wir den vollständigen Kontrollfluss nicht überprüfen können, d. H. Ich kann nicht sehen, wo jede Ihrer Funktionen aufgerufen wird. Aber ich bin mir ziemlich sicher, dass es Fehler bei der Array-Indexierung gibt.

Alle Arrays in C der Größe N haben Mitglieder 0. N-1. Ich sehe, dass Sie Arrays in main der Größe DIM zuweisen, aber später (in dist2 zum Beispiel) sehe ich Arrays von 1 bis DIM indiziert werden, was zu einer Out-of-Bound-Situation führt und etwas auf dem Stack überschreibt.

In redraw ich sehe:

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

und ich stelle fest, dass es außerhalb der Grenzen gehen. Dies sollte sein:

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

Ich schlage vor, Sie überprüfen gründlich alle Ihre Indizes und Array-Grenzen.