C

double p; int* S = malloc(n * sizeof(int)); p = (tr[i].a + tr[i].b + tr[i].c) / 2.0; S[i] = sqrt(p * (p - tr[i].a) * (p - tr[i].b) * (p - tr[i].c));

When assigning p, an arithmetic overflow can occur, since initially only int is calculated. Here a conversion into double would be necessary.

With the computation of S[] the decimal places are cut off and thus the result is wrong. With the comparison it can happen then that the order is not correct. It would also be better to check the return value of e.g. malloc.

If you use C++, it would be possible to use std::vector, which would be safer and more convenient

than malloc and free.

You could declare the data type triangle more simply:

C

// struct triangle { int a, b, c; }; // typedef struct triangle triangle; typedef struct { int a, b, c; } triangle;

It would also make sense to check if the triangle inequality is satisfied for a, b, c.