I need to find closest pair of four points C program. This code for three points. I need this solution for four point.
I tried this. This solution for three input.
When I entering the three points then I will get the closest but I need the closest point of four points.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct Point
{
int x, y ;
};
double getDistanceAB(struct Point a, struct Point b)
{
double distanceAB;
distanceAB = sqrt((a.x - b.x) * (a.x - b.x) + (a.y-b.y) *(a.y-b.y));
return distanceAB;
}
double getDistanceBC(struct Point b, struct Point c)
{
double distanceBC;
distanceBC = sqrt((b.x - c.x) * (b.x - c.x) + (b.y-c.y) *(b.y-c.y));
return distanceBC;
}
double getDistanceAC(struct Point a, struct Point c)
{
double distanceAC;
distanceAC = sqrt((a.x - c.x) * (a.x - c.x) + (a.y-c.y) *(a.y-c.y));
return distanceAC;
}
int main()
{
struct Point a, b, c;
printf("Enter coordinate of points a: ");
scanf("%d %d", &a.x, &a.y);
printf("Enter coordinate of points b: ");
scanf("%d %d", &b.x, &b.y);
printf("Enter coordinate of points c: ");
scanf("%d %d", &c.x, &c.y);
if((getDistanceAB(a,b))>(getDistanceBC(b,c)) && (getDistanceAB(a,b))>(getDistanceBC(a,c)))
{
printf("Point A and B are closest.");
}
else if((getDistanceBC(b,c))>(getDistanceAC(a,c)) && (getDistanceBC(b,c))>(getDistanceAC(a,b)))
{
printf("Point B and C are closest.");
}
else if((getDistanceBC(a,c))>(getDistanceAC(a,b)) && (getDistanceBC(a,c))>(getDistanceAC(b,c)))
{
printf("Point A and C are closest.");
}
else
{
printf("All point are same.");
}
}
First, change this:
double getDistanceAB(struct Point a, struct Point b)
{
double distanceAB;
distanceAB = sqrt((a.x - b.x) * (a.x - b.x) + (a.y-b.y) *(a.y-b.y));
return distanceAB;
}
double getDistanceBC(struct Point b, struct Point c)
{
double distanceBC;
distanceBC = sqrt((b.x - c.x) * (b.x - c.x) + (b.y-c.y) *(b.y-c.y));
return distanceBC;
}
double getDistanceAC(struct Point a, struct Point c)
{
double distanceAC;
distanceAC = sqrt((a.x - c.x) * (a.x - c.x) + (a.y-c.y) *(a.y-c.y));
return distanceAC;
}
to just this:
double getDistance(struct Point a, struct Point b)
{
double distance;
distance = sqrt((a.x - b.x) * (a.x - b.x) + (a.y-b.y) * (a.y-b.y));
return distance;
}
One of the main points of functions is that you don't have to repeat code.
Now all you have to do is create your four points by adding one more scan for the fourth point and add that to the decision tree.
Keep in mind this for the decision tree that you made... If you check if point 'a' is not the closest using the same logic you used in your original post, you don't have to compare point 'a' again.
I would reduce the number of functions to just double getDistance(struct Point p, struct Point o)
and keep your points in a list so you can allow the program to run through the points dynamically instead of programming each condition.
Once you have your points in a list, you can run a loop that checks each pair in the list for their distance and check that against the currently shortest distance; and if the distance of the pair checked is closer you change the currently shortest distance to the checked pair and which pair of points have that distance.
That way you can expand it to work for arbitrarily large number of points.
I'm not used to the syntax of C, but for the checking of points in the list you'll need a double for loop, in which the first goes through each point in the list, and the second checks the distance from/to that first point to all points later in the list.
for i = 0, i++, length(listOfPoints) {
for j = i+1, j++, length(listOfPoints) {
getDistance(listOfPoints[i], listOfPoints[j]
}
}
Hope this helps some.
This is how I'd solve that,
#include <stdio.h>
typedef struct
{
int x;
int y;
} Point;
int square(int x) { return x * x; }
int distanceSq(Point *a, Point *b)
{
return square(a->x - b->x) + square(a->y - b->y);
}
int main(int argc, char const *argv[])
{
int n = 4;
Point a[4];
for (int i = 0; i < n; i++)
{
printf("Enter Point %d <as x y>: ", i + 1);
scanf("%d %d", &a[i].x, &a[i].y);
}
int distance = __INT_MAX__;
int p1 = -1, p2 = -1;
for (int i = 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++)
{
int current = distanceSq(&a[i], &a[j]);
if (current < distance)
{
p1 = i;
p2 = j;
distance = current;
}
}
printf("The closest points are [%d %d] and [%d %d]", a[p1].x, a[p1].y, a[p2].x, a[p2].y);
return 0;
}
Note:
This can be extended for n number of points
Gives us the first pair closest points
we do not need to take square roots since if the square is large the square root will be proportionally large( in case of a large number(n) of points it might save computation time)
Here you go, a solution for any number of points.
Just change MAX_POINTS to anything you might need.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#define MAX_POINTS (4U)
struct Point
{
int x;
int y;
};
struct PointPair
{
struct Point a;
struct Point b;
};
double getDistance(const struct PointPair pair)
{
return sqrt((pair.a.x - pair.b.x) * (pair.a.x - pair.b.x) +
(pair.a.y - pair.b.y) * (pair.a.y - pair.b.y));
}
void readPoints(struct Point points[const])
{
for (unsigned i = 0; i < MAX_POINTS; i++)
{
printf("Enter coordinate of point %u: ", i);
scanf("%d %d", &(points[i].x), &(points[i].y));
}
}
bool checkForShorterDistance(const struct PointPair pair, double *const p_minDistance)
{
double tempDistance = getDistance(pair);
if (tempDistance < *p_minDistance)
{
*p_minDistance = tempDistance;
return true;
}
return false;
}
struct PointPair getClosestPair(const struct Point points[const])
{
struct PointPair result =
{
.a = points[0],
.b = points[1]
};
double minDistance = getDistance(result);
struct PointPair tempPair;
unsigned i, j;
for (i = 0; i < MAX_POINTS; i++)
{
tempPair.a = points[i];
for (j = 0; j < MAX_POINTS; j++)
{
if (i == j)
{
continue;
}
tempPair.b = points[j];
if (checkForShorterDistance(tempPair, &minDistance))
{
result = tempPair;
}
}
}
return result;
}
int main(void)
{
struct Point points[MAX_POINTS];
readPoints(points);
struct PointPair pair = getClosestPair(points);
printf("Closest pair is (%d, %d) and (%d, %d)\n",
pair.a.x,
pair.a.y,
pair.b.x,
pair.b.y);
return 0;
}
Related
I have the following code written. After i run the code it works fine until it tries to excecute the function add2Poly. Thereafter i get a segementation fault. I am new to programming so i cant understand what is causing it.
#include <stdio.h>
#include <stdlib.h>
struct poly{
double power[5];
double* coeff;
};
struct poly add2Poly(struct poly add1, struct poly add2)
{
struct poly p3;
p3.coeff = malloc(5 * sizeof * p3.coeff);
printf("We will add the two polynomials and put the result in a third polynomial p3.");
int size1 = sizeof(add1.coeff);
int size2 = sizeof(add2.coeff);
for(int i = 0; i < size1; i++)
{
int power = add1.power[i];
for(int j= 0; j < size2; j++)
{
if( power == add2.power[j])
{
p3.coeff[i] = add1.power[i] + add2.power[j];
p3.power[i] = add2.power[j];
}
}
}
return p3;
}
int main(){
struct poly p1;
p1.coeff = malloc(5 * sizeof * p1.coeff);
double a;
printf("Please enter a double value for poly1 coeff:");
scanf("%lf", &a);
double b;
printf("Please enter a double value for poly1 coeff:");
scanf("%lf", &b);
p1.coeff[1] = a;
p1.coeff[2] = b;
printf("Power of poly1: ");
scanf("%lf", &p1.power[1]);
printf("Power poly2: ");
scanf("%lf", &p1.power[2]);
printf("p1: %.1fx^%.1f", p1.coeff[1], p1.power[1]);
printf("+ %.1fx^%.1f\n", p1.coeff[2], p1.power[2]);
struct poly p2;
p2.coeff = malloc(5 * sizeof * p2.coeff);
double c;
printf("Please enter a double value for poly2 coeff:");
scanf("%lf", &c);
double d;
printf("Please enter a double value for poly2 coeff:");
scanf("%lf", &d);
p2.coeff[1] = c;
p2.coeff[2] = d;
printf("Power of poly1: ");
scanf("%lf", &p2.power[1]);
printf("Power poly2: ");
scanf("%lf", &p2.power[2]);
printf("p2: %.1fx^%.1f", p2.coeff[1], p2.power[1]);
printf("+ %.1fx^%.1f\n", p2.coeff[2], p2.power[2]);
struct poly p3;
p3.coeff = malloc(5 * sizeof * p3.coeff);
p3 = add2Poly(p1,p2);
printf("p3: %.1fx^%.1f", p3.coeff[1], p3.power[1]);
printf("+ %.1fx^%.1f\n", p3.coeff[2], p3.power[2]);
}
to be precise it gives me the following error:
segmentation fault(core dumped). I assume it has something to do with the p3 struct but i am not sure.
You want to initialize power by add1.power[i](line 18) when you have not assigned a value of add1.power[i], because at the first iteration i = 0
Then you have not assigned a value of add1.power[0], but only add1.power[1] and add1.power[2] (add1 = p1) and you want use it,
which means that conditional jump depends on uninitialised value : if( power == add2.power[j]) line 22, power is NULL also add2.power[j]
Delete lines 14 and 15 it does not serve you because
sizeof(add1.coeff) return the size in bytes of a pointer to double on your system : the result = 8 here.
You'll have an invalid read, your array poly.power and poly.coeff have a size of 5 while you want to read up to 8 values.
that's why you have this error segmentation fault(core dumped), Because you want to access a memory location that was not allocated to it.
Starting with your idea, if you want your code to work change the loop interval to 1 and 3: because only poly.power[1], poly.power[2], poly.coeff[1] and poly.power[2] are initialized.
Also in line 24 & 25 Do the sum of coefficients and not the sum of power to get the coefficients of the 3rd polynomial.
The way you define the structure of your polynomial can be changed, knowing only the degree of the polynomial. You can avoid the nested loop in your add2Poly function too.
I hope that will heplp you !
Look at the following code:
struct poly add2Poly(struct poly add1, struct poly add2)
{
struct poly p3;
p3.coeff = malloc(5 * sizeof *p3.coeff);
printf("We will add the two polynomials and put the result in a third polynomial p3.\n");
int size1 = sizeof(add1.coeff);// to delate
int size2 = sizeof(add2.coeff);// to delate
for (int i = 1; i < 3; i++)
{
int power = add1.power[i];
for (int j = 1; j < 3; j++)
{
if (power == add2.power[j])
{
p3.coeff[i] = add1.coeff[i] + add2.coeff[i];// do the sum of coefficients and not the sum of power
p3.power[i] = add2.power[i];
}
}
}
return p3;
}
here is an optimized proposal of your problem
#include <stdio.h>
#include <stdlib.h>
struct poly
{
int degree;
double *coeff; // the number of coefficient is equal to degree +1
};
struct poly add2Poly(struct poly p1, struct poly p2)
{
struct poly p3;
struct poly p_min_degree;
if (p1.degree > p2.degree)
{// the degree of the polynomial p3 is the one which has the greatest degree between p1 and p2
p3 = p1;
p_min_degree = p2;
}
else
{
p3 = p2;
p_min_degree = p1;
}
for (int i = 0; i <= p_min_degree.degree; i++)
{
p3.coeff[i] += p_min_degree.coeff[i];
}
return p3;
}
struct poly create_poly()
{// Ask the user to enter the degree of the polynomial and (degree +1) coefficients
struct poly p;
printf("Power of the polynomial : ");
scanf("%d", &p.degree);
p.coeff = malloc((p.degree + 1) * sizeof *p.coeff);
for (int i = 0; i <= p.degree; i++)
{// Read a double as coeff
printf("Enter the coeff x^%d : ", i);
scanf("%lf", &p.coeff[i]);
}
return p;
}
void display_poly(struct poly p)
{// Displays a polynomial p passed as a parameter
//Display example: p degree 2
//p = + 3.00x^2 + 4.00x^1 + 2.00x^0
printf(" p = ");
for (int i = p.degree; i >= 0; i--)
{
printf("+ %.2lfx^%d ", p.coeff[i], i);
}
printf("\n");
}
int main()
{
struct poly p1 = create_poly();
display_poly(p1);
struct poly p2 = create_poly();
display_poly(p2);
struct poly p3 = add2Poly(p1, p2);
printf("The sum of p1+p2 is :");
display_poly(p3);
}
So, I had been trying to write the code for the Small Triangles, Large Triangles problem of C in Hackerrank. Before, I state what problem I'm facing, I'll attach the question-
I only wrote the sort_by_area, swap and area functions here. The rest of it was given and unchangeable. The code I've written is getting executed properly but the structures aren't getting sorted correctly. Here is the expected output & my output-
I just cannot figure out why it is getting such weirdly swapped. If anyone could help, would mean a lot.
My code is-
#include <stdlib.h>
#include <math.h>
struct triangle
{
int a;
int b;
int c;
};
typedef struct triangle triangle;
void sort_by_area(triangle* tr, int n) {
int i, j, swapped;
for (i = 0; i < n-1; i++)
{
swapped = 0;
for (j = 0; j < n-i-1; j++)
{
if (area(tr[j].a, tr[j].b, tr[j].c) > area(tr[j+1].a, tr[j+1].b, tr[j+1].c))
{
swap(&tr[j], &tr[j+1]);
swapped = 1;
}
}
if (swapped == 0)
break;
}
}
void swap(struct triangle **xp, struct triangle **yp)
{
struct triangle *temp = *xp;
*xp = *yp;
*yp = temp;
}
int area(int a, int b, int c){
int p=(a+b+c)/2;
int q=p*(p-a)*(p-b)*(p-c);
return sqrt(q);
}
int main()
{
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}```
Enable all warnings
This quickly led to swap() swapping pointers and not data.
// Corrected - swap data
void swap(struct triangle *xp, struct triangle *yp) {
struct triangle temp = *xp;
*xp = *yp;
*yp = temp;
}
Function order
Move area(), swap() definitions before calling them.
Area
(int) sqrt(q) may return the same value for different qs.
Example: (int) sqrt(100), (int) sqrt(110), (int) sqrt(120)
All return 10. Sorting will not certainly sort according to area.
Simple return the square of the area. Mathematically, sorting by area squared same as area.
int area_squared(int a, int b, int c){
int p=(a+b+c)/2;
int q=p*(p-a)*(p-b)*(p-c);
// return sqrt(q);
return q;
}
Although one could code using double, let us stay with integers.
Watch out for a+b+c as odd as odd/2 forms a truncated quotient.
Perhaps return the square of the area, scaled each side by 2?
int area_squared2(int a, int b, int c){
a *= 2; b *= 2; c *= 2;
// a+b+c is certianly even
int p=(a+b+c)/2;
int q=p*(p-a)*(p-b)*(p-c);
return q;
}
A remaining concern is int overflow. Consider long long math.
long long area_squared2LL(int a, int b, int c){
long long aa = a * 2LL;
long long bb = b * 2LL;
long long cc = c * 2LL;
long long pp = (aa+bb+cc)/2;
long long qq = pp*(pp-aa)*(pp-bb)*(pp-cc);
return qq;
}
Tip: Allocate by referenced data, not type
Easier to code right, review and maintain.
// triangle *tr = malloc(n * sizeof(triangle));
triangle *tr = malloc(sizeof *tr * n);
if (tr == NULL) {
// use tr
...
free(tr);
tr = NULL;
}
I have this one task. To make it more clear, I am gonna use picture below as an example. Input and output is separated with dotted line. First line of input is number N - number of sets. For every set, it's first line are 2 numbers - first one declares how many numbers am I gonna process and second one is number of intervals. Second line specifies the numbers to process and third line contains 2 numbers X and Y, which create and interval. For every interval I have to output 3 numbers - lowest number on interval, index of highest number on interval and XOR of all numbers. Everything is running fine except it is really slow for big data and I have no idea how to make work faster. I have attached my code and large data input as well.
input.txt
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int id;
int index;
} Censor;
int Xor(const int x, const int y, const Censor array[]) {
int xor = array[x].id;
if (x == y) {
return xor;
}
for (int i = x + 1; i <= y; i++) {
xor ^= array[i].id;
}
return xor;
}
int int_cmp(const void *a, const void *b) {
const Censor *ia = (const Censor *)a;
const Censor *ib = (const Censor *)b;
return (ia->id - ib->id);
}
int LowestId(const int x, const int y, Censor array[]) {
int id = array[x].id;
if (x == y) {
return id;
}
qsort(array, y - x + 1, sizeof(Censor), int_cmp);
return array[0].id;
}
int HighestIdIndex(const int x, const int y, Censor array[]) {
int index = array[x].index;
if (x == y) {
return index;
}
qsort(array, y - x + 1, sizeof(Censor), int_cmp);
return array[y].index;
}
int main() {
int t, n, q, b, e;
int max = 100;
int count = 0;
int *output = (int *)malloc(max * sizeof(output));
scanf("%d", &t); //number of sets
for (int i = 0; i < t; i++) {
scanf("%d %d", &n, &q);
//I am making 3 separate arrays for numbers, because some of them are being sorted and some of them not
Censor lowest_id[n];
Censor highest_id_index[n];
Censor xor[n];
//This loop fills arrays with the numbers to be processed
for (int j = 0; j < n; j++) {
scanf("%d", &(lowest_id[j].id));
lowest_id[j].index = j;
highest_id_index[j].id = lowest_id[j].id;
highest_id_index[j].index = j;
xor[j].id = lowest_id[j].id;
xor[j].index = j;
}
// Now I am scanning intervals and creating output. Output is being stored in one dynamically allocated array.
for (int k = 0; k < q; k++) {
scanf("%d %d", &b, &e);
if (count + 3 >= max) {
max *=2;
int *tmp = (int *)realloc(output, max * sizeof(tmp));
if (tmp == NULL) {
return 1;
} else {
output = tmp;
}
}
output[count++] = LowestId(b, e, lowest_id);
output[count++] = HighestIdIndex(b, e, highest_id_index);
output[count++] = Xor(b, e, xor);
}
}
printf("---------------------\n");
for (int i = 0; i < count; i++) {
printf("%d\n", output[i]);
}
free(output);
return 0;
}
Thanks #Dan MaĊĦek and #Alex Lop. Sorting subarray in this case was unnecessary. Much easier is to iterate through the subarray in linear complexity.
I am having issues storing data from a file into my dynamic array. I am aware that what I have now is incorrect but it is just there for the moment. I have a file which on the first line contains the amount of lines of data essentially. The following lines have two integers side by side to represent an ordered pair. I want to store those two integers into a struct, point, that symbolizes an ordered pair. Also, the there is an array with such a struct that is inside of another struct, list , which contains the size of the array, or the amount of data currently stored in the array and a capacity which is the total amount of space in the array.
I want to store the two integers into variables of type int and then store them into a point inside of my array that is in my list struct.
I am getting very confused having two structs and am unsure if this is the correct approach. Any feedback would be welcomed.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
typedef struct
{
int x;
int y;
} point;
typedef struct
{
int size;
int capacity;
point *A;
} list;
// Compute the polar angle in radians formed
// by the line segment that runs from p0 to p
double polarAngle(point p, point p0)
{
return atan2(p.y - p0.y, p.x - p0.x);
}
// Determine the turn direction around the corner
// formed by the points a, b, and c. Return a
// positive number for a left turn and negative
// for a right turn.
double direction(point a, point b, point c)
{
return (b.x - a.x)*(c.y - a.y) - (c.x - a.x)*(b.y - a.y);
}
int whereSmallest(point A[], int begin, int end, point p0)
{
point min = A[begin];
int where = begin;
int n;
for (n = begin + 1; n < end; n++)
if (polarAngle(A[n], p0) < polarAngle(min, p0))
{
min = A[n];
where = n;
}
return where;
}
void selectionSort(point A[], int N, point p0)
{
int n, s;
point temp;
for (n = 0; n < N; n++)
{
s = whereSmallest(A, n, N, p0);
temp = A[n];
A[n] = A[s];
A[s] = temp;
}
}
// Remove the last item from the list
void popBack(list *p)
{
int x;
x = p->size - 1;
p->A[x] = p->A[x + 1];
}
// Return the last item from the list
point getLast(list *p)
{
point value;
value = p->A[p->size];
return value;
}
// Return the next to the last item
point getNextToLast(list *p)
{
point value;
value = p->A[p->size - 1];
return value;
}
int main(int argc, const char *argv[])
{
point p0, P;
FILE *input;
list *p;
int N, n, x, y;
/*Assuming that the first piece of data in the array indicates the amount of numbers in the array then we record this number as a reference.*/
N = 0;
input = fopen("points.txt", "r");
fscanf(input, "%d", &N);
/*Now that we have an exact size requirement for our array we can use that information to create a dynamic array.*/
p = (point*)malloc(N*sizeof(point));
if (p == NULL)//As a safety precaution we want to terminate the program in case the dynamic array could not be successfully created.
return -1;
/*Now we want to collect all of the data from our file and store it in our array.*/
for (n = 0; n < N; n++)
{
fscanf(input, "%d %d", &P.x, &P.y);
p->A[n] = P.x;
p->A[n] = P.y;
}
fclose(input);
free(p);
return 0;
}
First of all, your code cannot be compiled because this
p->A[n] = P.x;
p->A[n] = P.y;
is wrong, it should be
p->A[n].x = P.x;
p->A[n].y = P.y;
because A has type point and you should access the members of the struct in order to assign values to them.
But this is just the begining of the problems, you didn't allocate space for the A pointer, so this will not work.
You need to allocate space for an instance of type list, which is done this way
p = malloc(sizeof(*p));
Then you need to initialize p's members, for which
p->values = malloc(N * sizeof(point));
p->capacity = N;
p->size = 0;
as you see space was allocated for the values member.
Check fscanf() to insure data integrity and avoid undefined behavior, if fscanf() fails you would never know with your code and you potentially access uninitialized variables which leads to Undefined Behavior.
Capture the values scanned from the file in two int variables and copy them to the array only if the where sucessfuly read
for (n = 0 ; ((n < N) && (fscanf(input, "%d%d", &x, &y) == 2)) ; n++)
/* check that the values were read from the file _______^ */
{
/* store them in the array */
p->values[n].x = x;
p->values[n].y = y;
p->size += 1;
}
Check that the file did open.
I suggest the following code
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
typedef struct
{
int x;
int y;
} point;
typedef struct
{
int size;
int capacity;
point *values;
} list;
// Compute the polar angle in radians formed
// by the line segment that runs from p0 to p
double polarAngle(point p, point p0)
{
return atan2(p.y - p0.y, p.x - p0.x);
}
// Determine the turn direction around the corner
// formed by the points a, b, and c. Return a
// positive number for a left turn and negative
// for a right turn.
double direction(point a, point b, point c)
{
return (b.x - a.x)*(c.y - a.y) - (c.x - a.x)*(b.y - a.y);
}
int whereSmallest(point values[], int begin, int end, point p0)
{
point min = values[begin];
int where = begin;
int n;
for (n = begin + 1; n < end; n++)
if (polarAngle(values[n], p0) < polarAngle(min, p0))
{
min = values[n];
where = n;
}
return where;
}
void selectionSort(point values[], int N, point p0)
{
int n, s;
point temp;
for (n = 0; n < N; n++)
{
s = whereSmallest(values, n, N, p0);
temp = values[n];
values[n] = values[s];
values[s] = temp;
}
}
// Remove the last item from the list
void popBack(list *p)
{
int x;
x = p->size - 1;
p->values[x] = p->values[x + 1];
}
// Return the last item from the list
point getLast(list *p)
{
point value;
value = p->values[p->size];
return value;
}
// Return the next to the last item
point getNextToLast(list *p)
{
point value;
value = p->values[p->size - 1];
return value;
}
int main(int argc, const char *argv[])
{
FILE *input;
list *p;
int N, n, x, y;
/*Assuming that the first piece of data in the array indicates the amount of numbers in the array then we record this number as a reference.*/
N = 0;
input = fopen("points.txt", "r");
if (input == NULL)
return -1;
if (fscanf(input, "%d", &N) != 1)
{
fclose(input);
return -1;
}
p = malloc(sizeof(*p));
if (p == NULL)
return -1;
/*Now that we have an exact size requirement for our array we can use that information to create a dynamic array.*/
p->values = malloc(N * sizeof(point));
p->capacity = N;
p->size = 0;
if (p->values == NULL)//As a safety precaution we want to terminate the program in case the dynamic array could not be successfully created.
{
free(p);
fclose(input);
return -1;
}
/*Now we want to collect all of the data from our file and store it in our array.*/
for (n = 0 ; ((n < N) && (fscanf(input, "%d%d", &x, &y) == 2)) ; n++)
{
p->values[n].x = x;
p->values[n].y = y;
p->size += 1;
}
fclose(input);
free(p->values);
free(p);
return 0;
}
As you can see there is another improvement you can do to the code, it's not too important but it would avoid using the N and n variables which are not necessary.
Note: before using a function, try to read throughly it's documentation, that will prevent all sorts of unexpected results, for example fscanf(), will help you understand my fixes more.
The variable p should be list p.
The points array allocation is p.A = (point*)malloc(N*sizeof(point));
In the filling loop, since A[n] is a point you can't assign it the int P.x or P.y. You can directly put values into the A[n] point like that:
for (n = 0; n < N; n++)
{
fscanf(input, "%d %d", &(p.A[n].x), &(p.A[N].y));
}
The size and capacity of the list should be initialized: p.capacity = N; right after succesfull memory allocation and p.capacity = n; after filling the array
And in the end you should call free(p.A) instead of free(p).
I keep getting the following error message when I run my code in debug.
Windows has triggered a breakpoint in Linear Equations 331.exe.
This may be due to a corruption of the heap, which indicates a bug in
Linear Equations 331.exe or any of the DLLs it has loaded.
Then it comes up with a break/continue.
The code uses a Gauss-Siedel Iterative method to solve a n x n system of linear equations. In this case I need to find the total amount of stretch (X) for 3 bungee cords in series,with 3 people (A,B,C) attached to it. Each solution has a different permutation of the people attached (i.e. A,B,C ; A,C,B ; B,A,C etc.)
We were supplied with a memory allocation header file called alloc.h, though I don't fully understand how it works which may be causing my problem. It worked fine before I started using ALLOCATE() for more variables. Any help in explaining why this is happening would be really helpful.
The main code is first. Header Files are at the bottom. Sorry if the code is a bit messy. I tried to comment as best as I could:
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "allocate.h"
#include "iter.h"
void position_solve(int n,int k,double X[], double x[],double order[]);
void inverse(int n, double A[],double X[],double b[]);
void swap(double *,double*);
void permute(int n, double a[]);
int noofpermutations();
void next(int n,double a[]);
void permutation(int n, double a[]);
int count = 0;
int main(void)
{
int i,j,k,num=0, n=3, p=noofpermutations(n);
double *A = NULL, *m = NULL, *X = NULL,* b= NULL,*K=NULL, *x=NULL, *order=NULL, *length=NULL;
/* Allocate the required memory */
ALLOCATE(A, double, n * n);
ALLOCATE(m, double, n * p);
ALLOCATE(b, double, n);
ALLOCATE(x, double, n * p);
ALLOCATE(K, double, n * p);
ALLOCATE(X, double, n);
ALLOCATE(order,double, n);
ALLOCATE(length,double,1);
/*Defining the Order of A,B,C jumpers where 1 = A, 2 = B, 3 = C*/
printf("+-----------------------------------------------------------------------------+\n");
printf("The Order of Bungee Jumpers A,B and C is represented by \n1,2,and 3 respectively. \n");
printf("\n+-----------------------------------------------------------------------------+\n");
for(i=0;i<n;i++){
order[i] = i+1;
b[i] = 0;
}
length[0] = 0;
/*Hardcoding k(spring constant),x(initial length of each bungee cord) and m(mass in kg) for 3 bunjee jumpers*/
K[0] = 50;
K[1] = 100;
K[2] = 50;
m[0] = -60*9.81;
m[1] = -70*9.81;
m[2] = -80*9.81;
x[0] = 20;
x[1] = 20;
x[2] = 20;
for(i=3;i<n*p;i++){
K[i] = 0;
m[i] = 0;
x[i] = 0;
}
/*Generate Permutations of K,m for the given Order of Bungee Jumpers */
permutation(n,K);
permutation(n,m);
permutation(n,order);
/*Calculate A matrix*/
for(k=0;k<p;k++){
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if(i==j){
A[i*n + j] = -K[k*n + i] - K[k*n + j];
}
else if(j == (i+1)){
A[i*n+j] = K[k*n + j];
A[j*n+i] = K[k*n + j];
}
else if(j>(i+1)){
A[i*n + j] = 0;
}
}
}
printf("\nFor a Bungee Jumper order %1.0lf %1.0lf %1.0lf :\n",order[k*n],order[k*n+1],order[k*n+2]);
/*Determine multiple X (stretch of bungee in m) vecotrs*/
/*Extract a single RHS vector (from B) into b*/
for(i=0;i<n;i++){
b[i]= m[k*n + i];
}
/*Perform Iterative Method*/
iter_solve(n, A, b, X);
/* Output X solutions*/
printf("\nX = [\n");
for (j = 0; j < n; j++) {
printf("%f ", X[j]);
printf("\n");
}
printf("]\n");
/*Determine Order of Jumpers*/
position_solve(n,k,X,x,order);
printf("--------------------------------------------\n\n");
/*If A,B,C Permutation find inverse*/
if(((int)(order[k*n])==1) && ((int)(order[k*n+1])==2)){
inverse(n,A,X,b);
}
}
/* Free allocated memory */
FREE(A);
FREE(b);
FREE(x);
FREE(X);
FREE(order);
FREE(length);
FREE(m);
return 0;
}
void iter_solve(int n, double A[], double b[], double x[])
{
int i, j, k = 0;
double sum, delta = 0.2, x_store;
/*Check for division by zero and guess X=Zeros*/
for(i=0;i<n;i++){
x[i] = 0;
if(fabs(A[i*n + i]) < ZERO){
//exit if division by zero occurs
printf("Division by zero occurs. Preconditioning A matrix may be required.");
exit(EXIT_FAILURE);
}
}
/*Perform Gauss-Seidel Iteration*/
while( (delta>TOL) && (k<MAX_ITER) ){
for(i = 0; i < n; i++){
x_store = x[i];
sum = 0;
/*Sum for j<i*/
for(j = 0;(j < i); j++){
sum += A[i*n +j]*x[j];
}
/*Sum for i>j*/
for((j=i+1);j<n;j++){
sum += A[i*n +j]*x[j];
}
//Determine X value for current iteration
x[i] = (b[i]- sum)/A[i*n + i];
/*Find the residual difference using L1-norm*/
if((k>0) && (delta>((fabs(x[i] - x_store)/fabs(x[i]))))){
delta = fabs(x[i] - x_store)/fabs(x[i]);
}
}
k++;
}
/*Print Number of iterations*/
printf("\nNumber of iterations: %d using a tolerance of %f \n",k,TOL);
}
void position_solve(int n,int k,double X[], double x[],double order[])
{
int j, position;
double length = 0;
for (j = 0; j < n; j++) {
//printf("%f ", X[j]);
position = (int)(order[k*n +j]);
length += X[j] + x[position];
printf("Bungee Jumper %i: %lf meters\n",position,length);
/*Reset X vector to zero*/
X[j] = 0;
printf("\n");
}
}
void inverse(int n, double A[],double X[],double b[])
{
int i,j;
double *Inv_A;
ALLOCATE(Inv_A, double, n * n);
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(i==j){
b[i]=1;
}
else{
b[i]=0;
}
}
iter_solve(n,A,b,X);
for(j=0;j<n;j++){
Inv_A[i*n +j] = X[j];
}
}
printf("\nInverse A = [\n");
for(i=0;i<n;i++){
for(j=0;j<n;j++){
printf(" %lf ",A[i*n +j]);
}
printf("\n");
}
printf(" ]\n");
FREE(Inv_A);
}
void swap(double *p1,double *p2)
{ double temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int noofpermutations(int n)
{ int permutations=1,i;
for(i=1;i<=n;i++)
permutations=permutations*i;
return permutations;
}
void next(int n,double a[])
{ int i;
for(i=0;i<n;i++){
if(count < noofpermutations(n)){
a[(count+1)*n + i] = a[count*n +i];
}
}
count++;
}
void permute(int n, double a[])
{ int j;
while(count<noofpermutations(n)){
for(j=0;j<n-1;j++)
{ swap(&a[count*n + j],&a[(count*n) + (j+1)]);
next(n,a);
}
swap(&a[(count*n)],&a[(count*n) + 1]);
next(n,a);
for(j=n-1;j>0;j--)
{ swap(&a[(count*n)+ j],&a[(count*n) + (j-1)]);
next(n,a);
}
swap(&a[(count*n) + (n-1)],&a[(count*n) + (n-2)]);
next(n,a);
}
}
void permutation(int n,double a[])
{
permute(n,a);
count = 0;
allocate.h
/*
* allocate.h
*
* Dynamic memory allocation macros
*/
#ifndef _allocate_h_
#define _allocate_h_
#include <stdio.h>
#include <stdlib.h>
#define ALLOCATE(VAR,TYPE,SIZE) \
{ \
(VAR) = (TYPE *) calloc ((SIZE), sizeof(TYPE)); \
if ((VAR) == NULL) { \
fprintf (stderr, "ALLOCATE: Memory allocation failed (%s:%d) [%d]\n", __FILE__, __LINE__, (SIZE)); \
exit (EXIT_FAILURE); \
} \
}
#define FREE(VAR) \
{ \
free ((VAR)); \
(VAR) = NULL; \
}
#endif
/*
* iter.h
*
* Routine for solving square systems of linear equations with
* multiple right-hand sides AX=B using Gauss-Seidel iterative methods
*/
/* Zero tolerance for double precision */
#define ZERO 1.0E-12
/* Tolerance for iteration relative change */
#define TOL 0.01
/* Maximum number of iterations */
#define MAX_ITER 500
void iter_solve(int n, double A[], double b[], double x[]);
/*
* Iterative solver, x = (b - LU * xp) / D
* Input:
* n = size of matrix A
* A = factorised A matrix, (nxn) stored by row
* b = right-hand side vector, (nx1)
* Output:
* x = solution vector, (nx1)
* Failure scenarios:
* Division by "zero"
*/
When his error occurs in the debugger, it should tell you where you are in the program that it occurs - hopefully this will let you identify which memory location is being corrupted.
Note that address, restart the program in the debugger, set a breakpoint for after the allocations occurs, then set a data breakpoint on that memory location and run to see who's trashing it.
dlls may cause heap corruption if the runtime library for linking of your project differs from the library's