adding two polynomials using dynamic arrays - c

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

Related

Closest pair of four points c program

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

Ensemble averaging over ten independent realizations

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
//#include<igraph.h>
#define NUM_VERTICES1 15000// No. of data for Newman Watts to be used 15000:
//#define strings 10 // No. of base strings to be used 160:
//Function for generating infection rate randomly:
void unifRand(double *x, double *x1, double *x2)
{
int i;
const int n = 200; // 20
srand(unsigned(time(NULL)));
for(i = 0; i < n - 1; i++)
{
//x2[i] = rand()/double(RAND_MAX); //generate random number for choosing the infected neighbors(m):
x[i] = (0.2)+(0.4-0.2)*rand()/double(RAND_MAX);
x2[i] = 0.02; // fix the neighbor m and check:
x1[i] = log(1-x[i]);// Infection rate lambda:
printf("%lf\t%lf\t%lf\t%d\t%d\t\n", x[i], x1[i],x2[i],rand(), RAND_MAX);
}
}
// Function 2:
struct Edge {
int vertex;
struct Edge * next;
};
// Inserts Node to the Linked List by Head Insertion - O(1)
// Returns address of head which is the newly created node.
struct Edge * addEdge(struct Edge * currentHead, int newVertex)
{
struct Edge * newHead
= (struct Edge *) malloc(sizeof(struct Edge));
newHead->vertex = newVertex;
newHead->next = currentHead;
return newHead;
}
int main()
{
FILE *wg = NULL;
FILE *ob = NULL;
wg = fopen("ncwang1.txt","w");
ob = fopen("obs.txt","w");
if(wg == NULL)
{
printf("Error in opening file wg!\n");
}
if(ob == NULL)
{
printf("Error in opening file ob!\n");
}
int vertices = 200, edges = 400, i; // 20,50:(100,50)
int strings = 160;
int nobs = 10;
int v1, v2;
double j;
int k;
double t=0.0;
double dt=0.1;
double b;
double x[vertices], x1[vertices];
double x2[vertices];
unifRand(x,x1,x2);
// printf("Enter the Number of Vertices -\n");
// scanf("%d", &vertices);
//printf("\nEnter the Number of Edges -\n");
// scanf("%d", &edges);
struct Edge * adjacencyList[vertices + 1];
// Size is made (vertices + 1) to use the
// array as 1-indexed, for simplicity
// initialize array:
for (i = 0; i <= vertices; ++i) {
adjacencyList[i] = NULL;
}
for (i = 0; i <= edges; ++i) {
//scanf(%d%d", &v1, &v2);
v1 = rand()%200;
v2 = rand()%200;
// Adding edge v1 --> v2
// Add edge from v1 --> v2
if(v1 != v2)
adjacencyList[v1] = addEdge(adjacencyList[v1], v2);
// Adding edge v2 --> v1
// Remove this if you want a Directed Graph
adjacencyList[v2] = addEdge(adjacencyList[v2], v1);
}
// Printing Adjacency List
printf("\nAdjacency List -\n\n");
for(j = 0; j < strings; j++){
for (i = 0; i <= vertices; ++i) {
printf("adjacencyList[%d] -> ", i);
struct Edge * traverse = adjacencyList[i];
while (traverse != NULL)
{
b = (double)j/vertices;
fprintf(wg,"%d \t%d \t\t%0.6lf\t\t%0.1lf\t\t%0.8lf\t\n", i, traverse->vertex,-(x1[i]*(traverse->vertex))/100,b,
x[i]);
//fprintf(ob,"%d\t%0.2lf\t%0.1lf\n",k,(-log(1-x[i])*(traverse->vertex)),b);
printf("%d -> ", traverse->vertex);
traverse = traverse->next;
}
printf("NULL\n");
}
}
return 0;
fclose(wg);
fclose(ob);
wg = NULL;
ob = NULL;
}
I have written the above code for a network reconstruction performance from a reseach paper. I have to plot 'b' versus (-log(1-x[i])*(traverse->vertex)) from the output. The authors of the paper have mentioned that "the results are obtained by ensemble averaging over 10 independent realizations. How I can implement this in my code. As I am new to statistical physics, I do not know how to implement. Any suggestions will be helpful. The current output gives only a single line at b = 0.1, 0.2..1.0 which is not the expected output.c

Speech recognition using kohonen network with MFCC features. How I set a distance between the neurons and their weights?

I don't know how to set a localization of each neuron in map. This is a neuron and map:
typedef struct _neuron
{
mfcc_frame *frames;
char *name;
double *weights;
int num_weights;
int x;
int y;
} neuron;
typedef struct _map
{
neuron *lattice;
int latice_size;
double mapRadius;
int sideX, sideY;
int scale;
} map;
If i have more of one word equal, how calculate a distance between the pattern input (word) and my neuron.
I not sure about the weights. I define the weights as the amount of mfcc features of a word, but in training I need to update this weight according to the distance between the neurons. I'm using the Euclidean distance between the neurons. But the doubt is how to update the weights. Here the code of init map and neurons
void init_neuron(neuron *n, int x, int y, mfcc_frame *mfcc_frames, unsigned int n_frames, char *name){
double r;
register int i, j;
n->frames = mfcc_frames;
n->num_weights = n_frames;
n->x = x;
n->y = y;
n->name = malloc (strlen(name) * sizeof(char));
strcpy(n->name, name);
n->weights= malloc (n_frames * sizeof (double));
for(i = 0; i < n_frames; i++)
for(j = 0; j < N_MFCC; j++)
n->weights[i] = mfcc_frames[i].features[j];
printf("%s lattice %d, %d\n", n->name, n->x, n->y);
}
init map:
map* init_map(int sideX, int sideY, int scale){
register int i, x, y;
char *name = NULL;
void **word_adresses;
unsigned int n = 0, count = 0;
int aux = 0;
word *words = malloc(sizeof(word));
map *_map = malloc(sizeof(map));
_map->latice_size = sideX * sideY;
_map->sideX = sideX;
_map->sideY = sideY;
_map->scale = scale;
_map->lattice = malloc(_map->latice_size * sizeof(neuron));
mt_seed ();
if ((n = get_list(words))){
word_adresses = malloc(n * sizeof(void *));
while (words != NULL){
x = mt_rand() %sideX;
y = mt_rand() %sideY;
printf("y : %d x: %d\n", y, x);
init_neuron(_map->lattice + y * sideX + x, x, y, words->frames, words->n, words->name);
word_adresses[count++] = words;
words = words->next;
}
for (i = 0; i < count; i++)
free(word_adresses[i]);
free(word_adresses);
aux++;
}
return _map;
}
In the Kohonen SOM, the weights are in the feature space, so that means that each neuron contains one prototype vector. If the input is 12 MFCCs, then each input might look like a vector of 12 double values, so that means each neuron has 12 values, one for each of the MFCCs. Given an input, you find the best matching unit, then move the 12 codebook values for that neuron towards the input vector a small amount that is based on the learning rate.

Storing data into a dynamic array with structs in C

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

Issues with pointers and realloc, with program crashed errors in C

In main.c
#include <stdio.h>
#include "poly.h"
int main (void)
{
struct poly *p0 = polySetCoefficient (polySetCoefficient (polySetCoefficient (polyCreate() , 0, 4.0), 1, -1.0), 10, 2.0);
//polyPrint (p0);
return 0;
}
In poly.c I've just included two functions that I am dealing with, it seems as though polySetCoefficient is the one that's giving me problems. I've commented out the printf statements, but I used those to determine where exactly the program crashes. Apparently, it actually goes through the whole function before it crashes, so I am not exactly sure where the error is coming from. Secondly, in my main.c file I am only calling two functions. Another issue is that everytime I go through polySetCoefficient, my previous entries are replaced with 0s. I think that could be because of the way I set elements in the array to 0, but I carefully made sure to set elements to 0 from the previous size of the array to the new size of the array, excluding the last index.
struct poly *polyCreate()
{
struct poly *q;
q = malloc(sizeof(struct poly));
q->c = malloc(sizeof(double));
q->c[0] = 0.0;
q->size = 0;
//printf("polyCreate: %g\n", q->c[0]);
return q;
}
struct poly *polySetCoefficient(struct poly *p, int i, double value)
{
//printf("%d\n", i*sizeof(double));
if (p->size < i)
{
printf("Old: %d, New: %d\n", sizeof(p->c)/sizeof(double), i);
p->c = realloc(p->c, i+1*sizeof(double));
printf("New: %d \n", sizeof(p->c));
for(int l = p->size; l <= i; l++ )
{
if(l != i)
{
p->c[l] = 0;
printf("set to 0\n");
}
else
{
p->c[l] = value;
printf("F:set to %g\n", p->c[i]);
}
}
printf("Did we come here?\n");
p->size = i;
} else {
p->c[i] = value;
}
printf("The %d'th coefficient is %g\n", i, p->c[i]);
printf("Cof 0: %g, Cof 1: %g, Cof 10: %g", p->c[0], p->c[1], p->c[10]);
return p;
}
In poly.h
struct poly
{
double *c;
int size, length;
};
struct poly *polyCreate();
struct poly *polyDelete(struct poly *p);
struct poly *polySetCoefficient (struct poly *p, int i, double value);
double polyGetCoefficient (struct poly *p, int i);
int polyDegree (struct poly *p);
void polyPrint (struct poly *p);
struct poly *polyCopy (struct poly *p);
struct poly *polyAdd (struct poly *p0, struct poly *p1);
struct poly *polyMultiply (struct poly *p0, struct poly *p1);
struct poly *polyPrime (struct poly *p);
double polyEval (struct poly *p, double x);
This version of the code compiles cleanly and runs plausibly (but not really correctly) without crashing.
One key change is the one identified by immibis in his answer, the corrected size calculation.
The other key change is not printing coefficient 10 when there is no coefficient 10 yet. If you attempt to print that sooner, then you invoke undefined behaviour; anything may happen.
I fixed some printf() formats; on a 64-bit machine, you need to use %zu (or %zd at a pinch) to print a size_t. I removed the unused length member of the structure. I really don't know how to format your single-line multi-call statement neatly. I don't mind slightly longer than 80 character lines, but I don't normally go as far as 120. I definitely prefer the p1 version, not least because it would be possible to error check as you go. At the moment, I've used assert(ptr != 0); where there should be an allocation error check.
Output:
The 0'th coefficient is 4
The 1'th coefficient is -1
Old: 1, New: 10
New: 8
p[1] set to 0
p[2] set to 0
p[3] set to 0
p[4] set to 0
p[5] set to 0
p[6] set to 0
p[7] set to 0
p[8] set to 0
p[9] set to 0
p[10] set to 2
Did we come here?
The 10'th coefficient is 2
Cof 0: 4, Cof 1: 0, Cof 10: 2
Note that you've clobbered the first coefficient with zero when you extended to 10.
Code:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
struct poly
{
double *c;
int size;
};
struct poly *polyCreate(void);
struct poly *polySetCoefficient(struct poly *p, int i, double value);
int main(void)
{
/* I don't know how to format this neatly! */
struct poly *p0 = polySetCoefficient(
polySetCoefficient(
polySetCoefficient(polyCreate(), 0, 4.0),
1, -1.0),
10, 2.0);
assert(p0 != 0);
/*
struct poly *p1 = polyCreate();
p1 = polySetCoefficient(p1, 0, 4.0),
p1 = polySetCoefficient(p1, 1, -1.0);
p1 = polySetCoefficient(p1, 10, 2.0);
*/
return 0;
}
struct poly *polyCreate(void)
{
struct poly *q = malloc(sizeof(struct poly));
assert(q != 0);
q->c = malloc(sizeof(double));
assert(q->c != 0);
q->c[0] = 0.0;
q->size = 1;
return q;
}
struct poly *polySetCoefficient(struct poly *p, int i, double value)
{
assert(p != 0);
if (p->size < i)
{
printf("Old: %zu, New: %d\n", sizeof(p->c)/sizeof(double), i);
p->c = realloc(p->c, (i+1)*sizeof(double));
assert(p->c != 0);
printf("New: %zu\n", sizeof(p->c));
for (int l = p->size; l <= i; l++)
{
if (l != i)
{
p->c[l] = 0;
printf("p[%d] set to 0\n", l);
}
else
{
p->c[l] = value;
printf("p[%d] set to %g\n", i, p->c[i]);
}
}
printf("Did we come here?\n");
p->size = i;
}
else
{
p->c[i] = value;
}
printf("The %d'th coefficient is %g\n", i, p->c[i]);
if (i >= 10)
printf("Cof 0: %g, Cof 1: %g, Cof 10: %g", p->c[0], p->c[1], p->c[10]);
return p;
}
The missing brackets here could be the problem:
p->c = realloc(p->c, i+1*sizeof(double));
Change it to:
p->c = realloc(p->c, (i+1)*sizeof(double));

Resources