0

I wrote a program that receive two polynoms and calculate their sum an multiplication.

The program gets a polynom at this form

"2   4   -5   1   0   6   6   4   -8   0   7   3"

and translate it into a polynom form: "8x^4+7x^3-5x-8"

I think I have a problem with the polynom sum function, because it does show the multiplication result.

This is the error I get:

*** Error in `./vpl_execution': realloc(): invalid next size: 0x000000000070c210
 ***                                                                            
/home/p18206/.vpl_launcher.sh: line 9: 25054 Aborted                 (core dumpe
d) ./vpl_execution   

and another error I get:

ome/p13634/.vpl_launcher.sh: line 9: 25304 Segmentation fault      (core dumpe
d) ./vpl_execution                                                              

I literally tried evreything, I know it is an allocation problem but I just don't see why.

So in the code below, Please check the function "print polySum". It is also possible that there is a problem with the funcion "sum same power poly" or "print polynom"

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    typedef struct monom {
        int coefficient;
        int power;
    }Monom;

    //defining bool data type
    typedef int bool;
    #define TRUE 1
    #define FALSE 0

    #define MEMORY_ERROR_EXIT -1

    void polyMerge(Monom* arr1, unsigned int size1, Monom* arr2, unsigned int size2, Monom* res);
    void polySort(Monom* polynom, unsigned int size);
    void removeElement(Monom* polynomArr, unsigned int size);
    Monom* sumSamePowerPoly(Monom* polynomArr, unsigned int* size);
    Monom* getPolynom(unsigned int* size);
    void printPolynom(Monom* polynom, unsigned int size);
    void printPolySum(Monom* polynom1, unsigned int size1, Monom* polynom2, unsigned int size2);
    void printPolyMul(Monom* polynom1, unsigned int size1, Monom* polynom2, unsigned int size2);
    void checkMemoryAllocation(void *ptr);

    void main()
    {
        Monom *polynom1, *polynom2;             // The input polynoms
        unsigned int polynom1Size, polynom2Size; // The size of each polynom

        printf("Please enter the first polynom:\n");
        polynom1 = getPolynom(&polynom1Size);   // get polynom 1

        printf("Please enter the second polynom:\n");
        polynom2 = getPolynom(&polynom2Size);   // get polynom 2

        printf("The multiplication of the polynoms is:\n"); // print the multiplication
        printPolyMul(polynom1, polynom1Size, polynom2, polynom2Size);
        printf("\n");

        printf("The sum of the polynoms is:\n"); // print the sum
        printPolySum(polynom1, polynom1Size, polynom2, polynom2Size);
        printf("\n");

        free(polynom1); // releasing all memory allocations
        free(polynom2);
    }

    Monom* getPolynom(unsigned int* size) {
        /*This function recieve data from user*/

        unsigned int phySize = 1, logSize = 0;
        int currCofficient, currPower;
        bool lContinue = TRUE; // a flag that keeps that signal if we should keep recieving input
        Monom* polyArr;
        polyArr = (Monom*)malloc(sizeof(Monom)*phySize);
        checkMemoryAllocation(polyArr);

        while (lContinue) { //while the user didn't press enter we keep on recieving input
            scanf("%d%d", &currCofficient, &currPower);
            if (currCofficient != 0) { //if the current cofficient is 0 we do nothing. Else we insert the input to the array
                                       //if the logic size equal to the physical size we double the phySize and reallocate array with the new size
                if (logSize == phySize) {
                    phySize *= 2;
                    polyArr = (Monom*)realloc(polyArr, sizeof(Monom)*phySize);
                    checkMemoryAllocation(polyArr);;
                }
                polyArr[logSize].coefficient = currCofficient; //we locate the input on the current position (logical size)
                polyArr[logSize].power = currPower;
                logSize++; //we increment logical size of the array
            }

            if (getchar() == '\n') // the user pressed enter - the flag is "turned off", and we stop receiving input
                lContinue = FALSE;
        }

        *size = logSize; //size recieve the value "log size" which is the actual size of the array
        polySort(polyArr, *size); //we sort the array based on power sizes
        polyArr = sumSamePowerPoly(polyArr, size); //we unite Monoms that has the same power
        return polyArr;
    }


    void polyMerge(Monom* arr1, unsigned int size1, Monom* arr2, unsigned int size2, Monom* res) {
        /*This function merges two Monom arrays into one monom array sorted by powers from the biggest power to the smallest one*/
        unsigned int i = 0, j = 0, k = 0;
        while (i < size1 && j < size2) {
            if (arr1[i].power > arr2[j].power)
                res[k++] = arr1[i++];
            else
                res[k++] = arr2[j++];
        }

        while (i < size1) //While i<size1 keep copying values from array 1 to result array
            res[k++] = arr1[i++];
        while (j < size2) //While j<size2 keep copying values from array 2 to result array
            res[k++] = arr2[j++];
    }
    void polySort(Monom* polynom, unsigned int size) {
        /*This function sort a Monom array from the biggest power to the smalles one*/
        Monom* temp;
        unsigned int i;
        if (size == 1)
            return;
        else {
            polySort(polynom, size / 2);
            polySort(polynom + size / 2, size - size / 2);
            temp = (Monom*)malloc(sizeof(Monom)*size); //We temporary allocate an array that will keep the result of the merge
            checkMemoryAllocation(temp);
            polyMerge(polynom, size / 2, polynom + size / 2, size - size / 2, temp);

            for (i = 0; i < size; i++) //We copy the temporary array into our data array
                polynom[i] = temp[i];
            free(temp); //We delete the allocated memory for the temporary array
        }
    }


    Monom* sumSamePowerPoly(Monom* polynomArr, unsigned int* size) {
        /*This function sum polynoms from the same degree to one polynom*/
        unsigned int i;
        for (i = 0; i < *size - 1; i++) { //We check for each Monom in the array if there are other monoms with the same power
            while (polynomArr[i].power == polynomArr[i + 1].power) { //while power of a monom is eqaul to the power of other monoms
                polynomArr[i].coefficient += polynomArr[i + 1].coefficient; //we add the next monom to the first one
                removeElement(polynomArr + i + 1, *size - i); //and remove the monom we just united into another cell
                *size -= 1;
            }
        }
        polynomArr = (Monom*)realloc(polynomArr, sizeof(Monom)*(*size));
        return polynomArr;
    }

    void removeElement(Monom* polynomArr, unsigned int size) {
        /*This function removes an element from array*/
        unsigned int i;
        for (i = 0; i < size; i++) { //We copy each cell into the prior one
            polynomArr[i] = polynomArr[i + 1];
        }
    }

    void printPolynom(Monom* polynom, unsigned int size) {
        /*This function prints polynom*/
        unsigned int i;
        for (i = 0; i < size; i++) {
            if (polynom[i].power > 1) //if the power is bigger than one that print this form: coffx^power
                printf("%dx^%d", polynom[i].coefficient, polynom[i].power);
            else if (polynom[i].power == 1) //else if the power is one than print this form: coffx
                printf("%dx", polynom[i].coefficient);
            else //else print this form: coff
                printf("%d", polynom[i].coefficient);
            if (i < size - 1 && polynom[i + 1].coefficient > 0) //if there is another element after the current element and its
                                                                //cofficient is larger than 0 - print "+"
                printf("+");
        }
    }
    void printPolySum(Monom* polynom1, unsigned int size1, Monom* polynom2, unsigned int size2) {
        /*This function print the sum of two polynoms*/
        unsigned int i, j;
        unsigned int size;
        size = size1 + size2; //We set the size of sum result to be size of both of the polynoms

    Monom* sumRes; //We create a sum result array
    sumRes = (Monom*)malloc(sizeof(Monom)*size);
    checkMemoryAllocation(sumRes);
    //We copy each element from both of the polynoms array into the result array
    for (i = 0; i < size1; i++)
        sumRes[i] = polynom1[i];
    for (i = size1, j = 0; i < size && j < size2; j++, i++) {
        sumRes[i] = polynom2[j];
    }
    polySort(sumRes, size); //We sort all of the elements by power size
    //We unite all of the cells who has the same power. This action actually sums both of the polynoms to one poly sum.
    sumRes = sumSamePowerPoly(sumRes, &size);
    printPolynom(sumRes, size); //We print sum reault
    free(sumRes); //We free the sum result array after printing it
}

void printPolyMul(Monom* polynom1, unsigned int size1, Monom* polynom2, unsigned int size2) {
    /*This function prints the multiplication of two polynoms*/
    unsigned int i, j, k, size;
    i = 0;
    Monom* mulRes;
    size = size1 * size2; //We set the size of sum result to be the multiplication of both of the polynoms size
    mulRes = (Monom*)malloc(sizeof(Monom)*size); //We create a multiplication result array in which we will store the result of multiplying polynoms
    checkMemoryAllocation(mulRes);
    Monom temp; //We creat a temporary data type monom in which we will save the calculation of each multiplication
                //We multiply the polynoms and keep the multiplication result in the mulRes array
    for (j = 0; j < size1; j++) {
        for (k = 0; k < size2; k++) {
            temp.coefficient = polynom1[j].coefficient*polynom2[k].coefficient;
            temp.power = polynom1[j].power + polynom2[k].power;
            mulRes[i++] = temp;
        }
    }
    polySort(mulRes, size); //We sort all of the elements by power size
    mulRes = sumSamePowerPoly(mulRes, &size); //We unite all of the cells who has the same power
    printPolynom(mulRes, size); //We print the multiplication result
    free(mulRes);  //We free the multiply result array after printing it
}

void checkMemoryAllocation(void *ptr)
/*This function check if the dynmic allocation we did has succseeded */
{
    if (ptr == NULL)
    {
        printf("Memory allocation error\n");
        exit(MEMORY_ERROR_EXIT);
    }
}

This is the expected result: The multiplication of the polynoms is: 64x^8+112x^7+49x^6-80x^5-198x^4-112x^3+25x^2+80x+64 The sum of the polynoms is: 16x^4+14x^3-10x-16

thank you so much for your time!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
sharon
  • 21
  • 2
  • Welcome to Stack Overflow. Please read [the help pages](http://stackoverflow.com/help), take [the SO tour](http://stackoverflow.com/tour), read about [how to ask good questions](http://stackoverflow.com/help/how-to-ask), as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). Lastly please learn how to create a [mcve]. – Some programmer dude Aug 05 '19 at 11:50
  • On an unrelated note, you probably would like to learn about the [C standard boolean types and the `` header file](https://en.cppreference.com/w/c/types/boolean). And in C [you don't need (and should not) cast the result of `malloc`](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – Some programmer dude Aug 05 '19 at 11:52
  • As for your crashes, most likely reason is that write out of bounds of your allocated memory, leading to *undefined behavior*. – Some programmer dude Aug 05 '19 at 11:54
  • I don't understand the logic of how to get that polynom form into the polynomial, can you explain it? – Owl Aug 05 '19 at 12:12
  • each pair of numbers is a cofficient and a power. if in a pair the coffiecient is '0' we ignore it and keep recieving input. in this example: 2 4 is 2x^4 -5 1 is -5x 0 6 is nothing (we ignore) 6 4 is 6x^4 -8 0 is -8 7 3 is 7x^3 and becuse 6x^4 and 2x^4 has the same power we combine them together into 8x^4 so the final polynom is: 8x^4+7x^3-5x-8 – sharon Aug 05 '19 at 12:24
  • @Someprogrammerdude where do I write out of bounds on my allocated memory? It will help alot if I could understand where do I do it.. – sharon Aug 05 '19 at 12:33
  • It's hard to tell, since you don't really provide a ***minimal*** example. If you can run this on your own system then memory debuggers like [Valgrind](http://valgrind.org/) can definitely help (remember to build with debug information). You can also debug yourself, by stepping through the code line by line in a debugger. Or try to remove parts of the code, piece by piece, until it works and then you know which part of the code that causes the error to manifest. – Some programmer dude Aug 05 '19 at 12:35
  • I tried debbuging, I could find any problem. On my compiler it works perfectly fine (I use visual studio). But on the school's compiler it prints the multiplication, than when it's time to print the sum it print the error I wrote to you instead. What is the minimal example you need? I'll be happy to provide one. thank you – sharon Aug 05 '19 at 12:43

1 Answers1

0

In function GetPolynom I found this :

   if (logSize == phySize) {
        phySize *= 2;
        polyArr = (Monom*)realloc(polyArr, sizeof(Monom)*phySize);
        checkMemoryAllocation(polyArr);;
   }

This means you are reallocating sizes that grow exponentially of the form sizeof(Monom) * 2^(n-1) being n the number of current loop in the "while" construct.

I think you should change

     phySize *= 2;

for

     phySize += 1;

Hope this helps.

marcelom
  • 71
  • 1
  • 4