Adding two polynomials in exponential form in C

88 views Asked by At

The question is to add two user defined polynomial data types. My code is given below. I tried to make a code which takes only the necessary memory by using malloc to create dynamic arrays.

Please help me correct this code. I am new to the concept of double pointers and dynamic arrays.

#include <stdio.h>

#include <stdlib.h>

typedef struct Polynomial {
    int numTerms;
    int ** expo;
    int ** coff;
}
polynomial;

void polyInput(polynomial poly) {
    int i;
    int * ptr1;
    int * ptr2;
    ptr1 = (int * ) malloc(sizeof(int) * poly.numTerms);
    ptr2 = (int * ) malloc(sizeof(int) * poly.numTerms);

    printf("Enter the pair of exponent and coefficient:\n");
    for (i = 0; i < poly.numTerms; i++)
        scanf("%d %d", & ptr1[i], & ptr2[i]);

    poly.expo = & ptr1;
    poly.coff = & ptr2;
}

void polyPrint(polynomial poly) {
    int i;
    for (i = 0; i < poly.numTerms; i++)
        printf("(%d, %d) ", ( * poly.expo)[i], ( * poly.coff)[i]);
}

polynomial polySum(polynomial poly1, polynomial poly2) {
    int n1 = poly1.numTerms;
    int n2 = poly2.numTerms;
    if (( * poly1.expo)[n1 - 1] > ( * poly2.expo)[n2 - 1]) {}
    return polySum(poly2, poly1);

    int i = 0, j = 0, k = 0;
    polynomial sumOfPoly;
    * sumOfPoly.coff = (int * ) malloc(50 * sizeof(int));
    * sumOfPoly.expo = (int * ) malloc(50 * sizeof(int));
    while (i < n1 && j < n2) {
        if (( * poly1.expo)[i] < ( * poly2.expo)[j]) {
            ( * sumOfPoly.expo)[k] = ( * poly2.expo)[j];
            ( * sumOfPoly.coff)[k] = ( * poly2.expo)[j];
            k++;
            j++;
        } else if ( * poly1.expo[i] > * poly2.expo[i]) {
            ( * sumOfPoly.expo)[k] = ( * poly1.expo)[i];
            ( * sumOfPoly.coff)[k] = ( * poly1.coff)[i];
            k++;
            i++;
        } else {
            // Check for special case
            if (( * poly1.coff)[i] + ( * poly2.coff)[j] != 0) {
                ( * sumOfPoly.expo)[k] = ( * poly1.expo)[i];
                ( * sumOfPoly.coff)[k] = ( * poly1.coff)[i] + ( * poly2.coff)[j];
                k++;
            }
            i++;
            j++;
        }
    }

    while (i < n1) {
        ( * sumOfPoly.expo)[k] = ( * poly1.expo)[i];
        ( * sumOfPoly.coff)[k] = ( * poly1.coff)[i];
        k++;
        i++;
    }

    sumOfPoly.numTerms = k;

    return sumOfPoly;
}

int main() {
    polynomial poly1, poly2;
    int i;

    printf("Enter the number of terns in 1st polynomial: ");
    scanf("%d", & poly1.numTerms);
    polyInput(poly1);

    printf("Enter the number of terms in 2nd polynomial: ");
    scanf("%d", & poly2.numTerms);
    polyInput(poly2);

    polynomial sumOfPoly;
    sumOfPoly = polySum(poly1, poly2);

    polyPrint(sumOfPoly);

    return 0;
}

The above code should take two polynomials from the user and then return and print the sum of the polynomials.

I am getting a no output after entering the data. I only got a segmentation fault. The output is:

Enter the number of terns in 1st polynomial: 3
Enter the pair of exponent and coefficient:
2 1
1 5
0 -3
Enter the number of terms in 2nd polynomial: 3
Enter the pair of exponent and coefficient:
3 2
2 -3
0 6
Segmentation fault

Please point out my mistake in this code and what should i change to correct it.

2

There are 2 answers

0
John Omielan On

In addition to the various issues mentioned in the comments, the main problem that's causing the segmentation fault is that you are passing the polynomial struct by value into your polyInput function. Thus, the program is taking a copy of your poly1 and poly2 objects when calling that function, so that copy is what's being updated, not the original objects. Thus, since they are not initialized, they contain whatever is in memory at the time, thus causing UB (Undefined Behavior), in particular the segmentation faults when the code is trying to access the pointers.

Here's sample code, based on your code but with a few changes, such as using the correct casts and initializing the poly1 struct, since my compiler, VS 2017, complains if I don't.

#include <stdio.h>
#include <stdlib.h>

typedef struct Polynomial {
    int numTerms;
    int ** expo;
    int ** coff;
}
polynomial;

void polyInput(polynomial poly) {
    poly.numTerms = 1;
    poly.expo = (int **) malloc(sizeof(int*) * poly.numTerms);;
    poly.coff = (int **) malloc(sizeof(int*) * poly.numTerms);;
}

void polyInput2(polynomial* poly) {
    poly->numTerms = 1;
    poly->expo = (int **) malloc(sizeof(int*) * poly->numTerms);;
    poly->coff = (int **) malloc(sizeof(int*) * poly->numTerms);;
}

int main()
{
    polynomial poly1 = {0, NULL, NULL}, poly2 = {0, NULL, NULL};

    polyInput(poly1);
    printf("%d %p %p\n", poly1.numTerms, poly1.expo, poly1.coff);

    polyInput2(&poly2);
    printf("%d %p %p\n", poly2.numTerms, poly2.expo, poly2.coff);

    return 0;
}

Note that polyInput and polyInput2 basically do the same thing, but the first uses pass by value, like your function, while the second one uses a pointer instead, so any changes there will also be in the object you pass to it.

Running it results in this output:

0 00000000 00000000
1 00CE4918 00CE4928

As you can see, the first set of values remain at the 0 ones I initialized it with, and only the second ones have the values set by the function.

0
chux - Reinstate Monica On

new to the concept of double pointers

It may be true for OP, yet double pointers are not needed here.

At least this problem:

Saving address of local variable

poly.expo = & ptr1; saves the address of local variable ptr1. Later code in other routines using .expo risks using an invalid pointer.

Instead, save the pointer of the allocation.

poly.expo = anything; is a problem as it saves into the local parameter poly, which does not affect calling code's argument.

Instead, calling code can pass the address of the polynomial object to polyInput().

typedef struct Polynomial {
    int numTerms;
    //int ** expo;
    //int ** coff;
    int *expo;
    int *coff;
}
polynomial;

//void polyInput(polynomial poly) {
void polyInput(polynomial *poly) {
    //int i;
    //int * ptr1;
    //int * ptr2;
    //ptr1 = (int * ) malloc(sizeof(int) * poly.numTerms);
    //ptr2 = (int * ) malloc(sizeof(int) * poly.numTerms);
    poly->expo = malloc(sizeof poly->expo[0] * poly.numTerms);
    poly->coff = malloc(sizeof poly->coff[0] * poly.numTerms);
    if (poly->expo == NULL || poly->coff == NULL) {
      Handle_error_with_TBD_code;
    }

    printf("Enter the pair of exponent and coefficient:\n");
    // for (i = 0; i < poly.numTerms; i++)
    for (int = 0; i < poly.numTerms; i++) {
        // scanf("%d %d", & ptr1[i], & ptr2[i]);
        scanf("%d %d", &poly->expo[i], &poly->coff[i]);
    }

    //poly.expo = & ptr1;
    //poly.coff = & ptr2;
}

// Calling code

    //polyInput(poly1);
    polyInput(&poly1);

Other

Check return value of scanf().