0

Given a triangle, I have to transform a triangle into another in the following way: rotate a given angle the vertex with respect to the origin, and then applied a homothety with respect to the origin. And save every triangle in n+1 vector, and then sort the vector according to the argument (angle between 0 and 2π) of the vertex a, with direct insertion.

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct{
float x;
float y; }point;
typedef struct {
point a;
point b;
point c; }triangle;

      float angle(triangle *t,int i){

float a,b,c,alpha;
 a=(t[i].b.x-t[i].c.x)*(t[i].b.x-t[i].c.x)+(t[i].b.y-t[i].c.y)*(t[i].b.y-t[i].c.y);
 b=(t[i].a.x-t[i].b.x)*(t[i].a.x-t[i].b.x)+(t[i].a.y-t[i].b.y)*(t[i].a.y-t[i].b.y);
   c=(t[i].a.x-t[i].c.x)*(t[i].a.x-t[i].c.x)+(t[i].a.y-t[i].c.y)*(t[i].a.y-t[i].c.y);
  alpha=acos((b*b+c*c-a*a)/(2*b*c));
 return alpha;} 

   void move(int r,float angle,triangle *t,int i){

float alpha;
 // rotation
     alpha=angle*M_PI/180;
        t[i+1].a.x=t[i].a.x*cos(alpha)-t[i].a.y*sin(alpha);
        t[i+1].a.y=t[i].a.x*sin(alpha)+t[i].a.y*cos(alpha);
    t[i+1].b.x=t[i].b.x*cos(alpha)-t[i].b.y*sin(alpha);
    t[i+1].b.y=t[i].b.x*sin(alpha)+t[i].b.y*cos(alpha);
    t[i+1].c.x=t[i].c.x*cos(alpha)-t[i].c.y*sin(alpha);
    t[i+1].c.y=t[i].c.x*sin(alpha)+t[i].c.y*cos(alpha);

// homotecy
    t[i+1].a.x=t[i+1].a.x*r;
    t[i+1].a.y=t[i+1].a.y*r;
    t[i+1].b.x=t[i+1].b.x*r;
    t[i+1].b.y=t[i+1].b.y*r;
    t[i+1].c.x=t[i+1].c.x*r;
     t[i+1].c.y=t[i+1].c.y*r;
       return;}

void sort(triangle *t,int n){

float a,b;
int k,i;
for(i=1;i<=n-1;i++){
    a=angle(t,i);
    k=i-1;
    b=angle(t,k);
    while(a>=0 && a<=(M_PI*2) && b>a){
        t[k+1]=t[k];
        k--;
    }
    t[k+1]=t[i];
}
return;}

 int main(void){

triangle *t;
float angle;
int r,n,i;
char so[50];
FILE *s;

printf("n?\n");
scanf("%d",&n);
printf("r?\n");
scanf("%d",&r);
printf("angle?\n");
scanf("%f",&angle);
t=(triangle*)malloc((n+1)*sizeof(point));
if(t==NULL) exit(1);
printf("Triangle?\n");
scanf("%f %f %f %f %f %f",&t[0].a.x,&t[0].a.y,&t[0].b.x,&t[0].b.y,&t[0].c.x,&t[0].c.y);
for(i=0;i<n;i++){
    move(r,angle,t,i);
    sort(t,n);
}
printf("file?\n");
scanf("%s",so);
s=fopen(so,"w");
if(s==NULL) exit(1);
for(i=0;i<n;i++){
    fprintf(s,"%9.5f %9.5f %19.5f %9.5f %9.5f %9.5f\n",t[i].a.x,t[i].a.y,t[i].b.x,t[i].b.y,t[i].c.x,t[i].c.y);
}
fclose(s);  
free(t);
   return 0;}

When executing it says:

free(): invalid next size (normal)
Obsidian
  • 3,719
  • 8
  • 17
  • 30
ari lp
  • 3
  • 1
  • 3
    This code is not readable. The error suggest that you are corrupting your allocated memory somehow or changing the pointer value. – Eugene Sh. May 22 '19 at 19:16
  • How I can solved it? – ari lp May 22 '19 at 19:18
  • 3
    See the first part of my comment. – Eugene Sh. May 22 '19 at 19:18
  • 1
    Without validation of the return from `scanf` on EVERY user input, it is impossible to know whether `scanf("%d",&n);` succeeded and whether `malloc((n+1)*sizeof(point));` allocated anything at all -- which could easily lead to your error. – David C. Rankin May 22 '19 at 19:19
  • 3
    @arilp Look at this line: `t=(triangle*)malloc((n+1)*sizeof(point));`. You allocate points while you wanted to allocate triangles. Then, you write into memory that you do not own and you corrupt it. – Gilles-Philippe Paillé May 22 '19 at 19:22

1 Answers1

2

Change the following line:

t=(triangle*)malloc((n+1)*sizeof(point)); to

t=(triangle*)malloc((n+1)*sizeof(triangle)); or even

t = malloc((n+1) * sizeof *t); to avoid casting and dealing with the type of t.

You allocate points while you wanted to allocate triangles. Then, you write into memory that you do not own and you corrupt it. This could have lead to a segmentation fault. In your case, you were lucky (or unlucky if you consider that you would have caught the bug before) and you got the error when freeing the allocated memory. From my experience, an error when freeing memory is almost always memory corruption and sometimes a double free if you are not careful.

  • 1
    Better still: `t = malloc((n+1) * sizeof *t);`, which (a) fixes the problem, (b) is arguably more readable, and (c) honors what all C programs should strive for: [not casting `malloc`](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). More characters on-screen does not necessarily equate to better code. – WhozCraig May 22 '19 at 19:28
  • @arilp Great! Glad that I could help. Please consider accepting the answer if it solved your problem. – Gilles-Philippe Paillé May 22 '19 at 19:28
  • @WhozCraig Thanks for the tip, I will add it to the answer. – Gilles-Philippe Paillé May 22 '19 at 19:30