I am trying to create a polynomial from a group of monomials, with a structure for both. I have an append function which is failing due to an invalid write error, and know I need to allocate space for the new monomial, but am not sure how to go about it. Any help would be greatly appreciated:
typedef struct Monomial {
typede Monomial {
int coeff; /* coefficient */
int exp; /* exponent */
struct Monomial *next; /* next monomial */
} Mono;
typedef struct Polynomial {
int deg; /* degree */
Mono* first; /* first monomial */
Mono* last; /* last monomial */
} Poly;
This function creates a new monomial with a given coefficient and power. c : the coefficient k : the power The function allocates a monomial and initializes its attributes. The return value is a pointer to the newly created monomial.
Mono* newMono( int c, int k) {
Mono m = {c, k, (Mono*)malloc(sizeof(Mono)) };
Mono * mp = (Mono*)malloc(sizeof(m));
return mp;
}
This function creates a new (empty) polynomial with degree 0 and no monomials.
Poly* newPoly() {
int deg = 0;
Mono * first = NULL;
Mono * last = NULL;
Poly p = {deg, first, last};
Poly * point= (Poly*)malloc(sizeof(p));
return point;
}
}
This functions adds a monomial inside a polynomial p : the polynomial to modify m : the monomial to add The polynomial p is expected to be the sole owner of m. The new monomial should be added at the end of the list. The degree of the monomial should not exceed the degree of the polynomial
void appendMono( Poly* p, Mono* m) {
if((*p).first){
Mono* l = (*p).last;
(*l).next = m; //ERROR IS HERE
(*p).last = m;
}
else {
(*m).next = (Mono*)malloc(sizeof(Mono));
(*p).first=m;
(*p).last=m;
}
}
This function allocates, reads and returns a polynomial. It starts by asking the highest degree Then it reads all the monomials (which are given in increasing order of powers) as pairs of integers (whitespace separated) and adds them to the polynomial. It finally returns the constructed poly.
Poly* readPoly() {
//TODO
Poly* p = newPoly;
int deg;
int pow, coef;
scanf("%d", °);
while(scanf("%d %d", &pow, &coef)){
Mono * m = newMono(pow, coef);
appendMono(p, m); //ERROR CALLED FROM HERE
}
return p;
}
You're pretty far away from working code.
This doesn't do what you think:
Mono* newMono( int c, int k) {
Mono m = {c, k, (Mono*)malloc(sizeof(Mono)) };
Mono * mp = (Mono*)malloc(sizeof(m));
return mp;
}
Malloc returns uninitialized storage, so this function returns junk. It's also useless to cast the return value of malloc
. Just make sure you have #include <stdlib.h>
in the program head.
Try this:
Mono *newMono(int coeff, int exp) {
Mono *p = malloc(sizeof *p); // Check for NULL return in production code
p->coeff = coeff;
p->exp = exp;
p->next = NULL;
return p;
}
Follow the same pattern for newPoly
. You're apparently trying to build an aggregate and then copy it into malloc
ed memory. That will work, but it's wasteful unless your compiler is smart enough to eliminate the extra copy. Just do it the straightforward way.
To append, there is no need to allocate any new storage. You're only adjusting pointers.
void appendMono(Poly *p, Mono *m) {
if (p->first) {
p->last->next = m;
p->last = m;
} else {
p->first = p->last = m;
}
}