NoHoly
NoHoly

Reputation: 43

Incorrect values are being assigned - C

This question was kind of hard to look for in the website. I tried but came back empty handed, so I'm sorry if a similar question has been asked before.

Essentially, I have a piece of code with two for loops. I believe its purpose is unnecessary for the question I'm asking. Anyway, the second time this function is called in my code (it works fine the first time) the values assigned to variables x and y are incorrect.


void draw_sprite(Sprite *sp){

 printf("outside cicle\nx: %d\ny: %d\n", (sp->x), (sp->y));

 int y;
 int x;

 int p = 0;
 for(y = sp->y; y < (sp->y + sp->height); y++){
   for(x = sp->x; x < (sp->x + sp->width); x++){
     printf("inside cicle\nx: %d\ny: %d\n", x, y);
     vg_paint_pixel(x, y, sp->map[p]);
     p++;
   }
 }

 return;
}

The program prints out:

outside cicle
x: 34
y: 30
inside cicle
x: 0
y: 136663040

As you see, before assigned, the values are 34 and 30 for x and y respectively. But after assigning them, the variables x and y become 0 and 136663040. Thanks in advance.

Definition of sp:

typedef struct {
  int x,y;             
  int width, height;   
  int xspeed, yspeed;  
  char *map;           
} Sprite;

This function's parameter (draw_sprite) is a sprite created the following way:

Sprite *sp;

sp = create_sprite(xpm, xi, yi, 0, 0);

These values are given through the terminal and I'm using an xpm map that works unless I have to move the sprite. Values xi and yi were both 30. Here is the function create_sprite:

Sprite * create_sprite(xpm_map_t xpm, int x, int y, int xspeed, int yspeed){

  Sprite *sp = (Sprite *) malloc ( sizeof(Sprite));

  if(sp == NULL){
    return NULL;
  }

  xpm_image_t img;

  sp->map = (char*)xpm_load(xpm, XPM_INDEXED, &img);

  if(sp->map == NULL){
    free(sp);
    return NULL;
  }

  sp->width = img.width;
  sp->height = img.height;
  sp->x = x;
  sp->y = y;
  sp->xspeed = xspeed;
  sp->yspeed = yspeed;

  return sp;
}

Also, as used to compile and generate said error:

int(video_test_move)(xpm_map_t xpm, uint16_t xi, uint16_t yi, uint16_t xf, uint16_t yf,
                     int16_t speed) {

  Sprite *sp;

  sp = create_sprite(xpm, xi, yi, 0, 0);

  if (sp == NULL) {
    printf("Error creating sprite.\n");
    return 1;
  }

  sp->xspeed = speed;

  draw_sprite(sp);

  if (speed > 0) {

            while(sp->x != xf || sp->y != yf)){
              destroy_sprite(sp);
              sp->x += sp->xspeed;
              sp->y += sp->yspeed;
              draw_sprite(sp);
            }      

  }

return 0;
}

Finally, for the code to work, there's also destroy_sprite:

void destroy_sprite(Sprite *sp){
  if(sp == NULL){
    return;
  } 

  if(sp->map){
    free(sp->map);
  }

  free(sp);
  sp = NULL;
}

Upvotes: 0

Views: 113

Answers (1)

kopecs
kopecs

Reputation: 1731

Based on the comments the specific issue sounded like it was in

while(sp->x != xf || sp->y != yf)){
    destroy_sprite(sp);
    sp->x += sp->xspeed;
    sp->y += sp->yspeed;
    draw_sprite(sp);
}

Namely the fact that you ran into undefined behaviour as a result of using sp after freeing it. This caused (in your case) you to read garbage values resulting in an unexpected amount of iteration in your for loops.

Upvotes: 1

Related Questions