0

I need to write a function that sums monoms with the same power, the monoms are defined by the following struct:

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

And the function I wrote from the job is:

int sumMonomsWithSamePower(MONOM** polynomial, int size)
{
        int i, powerIndex = 0;

        for (i = 0; i < size; i++)
        {
            if ((polynomial[powerIndex])->power == (polynomial[i])->power)
                {
                        if (powerIndex != i)
                                (polynomial[powerIndex])->coefficient += (polynomial[i])->coefficient;

                }

                else
                        powerIndex++;
        }

        powerIndex++;
        *polynomial = (MONOM*)realloc(polynomial, powerIndex);
        return powerIndex;
}

Which is being called with the following call:

*polySize = sumMonomsWithSamePower(&polynomial, logSize);

polynomial array is being sent to the function as a sorted array of MONOMs (sorted ascending by powers).

My problem is that on the 7th line of sumMonomsWithSamePower() the function crashes since it can't see the elements in the array by the following way. When I put the elements of the array in Watch list in my debugger I also can't see them using polynomial[i], but if I use (polynomial[0]+i) I can see them clearly.

What is going on here?

Quaker
  • 1,483
  • 3
  • 20
  • 36
  • 2
    You **still** don't need a double pointer, nor should you cast the return value of `realloc()`. –  Jul 19 '13 at 14:38
  • @H2CO3, I'm not there yet, the function doesn't even get `realloc()`. – Quaker Jul 19 '13 at 14:39
  • @H2CO3 and I think you're wrong with the casting, since `realloc()` is a `void *` function I *need* explicit casting. – Quaker Jul 19 '13 at 14:40
  • @Quaker [No, **you** are wrong.](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858) –  Jul 19 '13 at 14:41
  • That's not what my compiler says `IntelliSense: a value of type "void *" cannot be assigned to an entity of type "MONOM *"` – Quaker Jul 19 '13 at 14:43
  • Compile C code as C, not as C++. They're different languages with different rules. (Checked out the link?) –  Jul 19 '13 at 14:43
  • Sure, I'm not arguing to flame but to learn. – Quaker Jul 19 '13 at 14:44
  • @H2CO3, The casting is not the issue here (and not what makes the troubles) but I think that your point about double pointer might solve my problem. I send an array to the function and I want to get a new array, doesn't it mean that I must use a double pointer? – Quaker Jul 19 '13 at 14:48
  • not quite - a simple array already decays into a pointer, so by swapping its elements, you can reorder the array in-place. –  Jul 19 '13 at 14:50
  • @H2CO3, But the array after summation might be smaller, so I want to realloc and free the useless memory – Quaker Jul 19 '13 at 14:52
  • may be "if (((*polynomial)[powerIndex])->power == ((*polynomial)[i])->power)" ? since you have pointer to pointer which points to pointer which points to some address on the heap ^^ – kvv Jul 19 '13 at 14:53
  • @Quaker Unless you are dealing with millions of elements, don't realloc to shrink the array. Only extend it when necessary. Chances are that due to paging and other considerations, you won't bee freeing any memory or you will only increase fragmentation. Try to reduce the number of calls to memory allocator functions, they're expensive. –  Jul 19 '13 at 14:53
  • @H2CO3, I actually have to free unused memory since it's in the guidelines for my university homework assignment :-\ – Quaker Jul 19 '13 at 14:55
  • @Quaker Your instructor doesn't know jack about OSes' memory management techniques (what a shame). Still, better use a 1D-array, then return the new size, and shrink it outside the function. –  Jul 19 '13 at 14:56
  • What kw said. And perhaps *polynomial in the realloc – Jiminion Jul 19 '13 at 14:57
  • Besides the allocation problems: what I don't understand is `else powerIndex++`. Assume your MONOMs 0-2 have the same power, then you examine `i==3` and set `powerIndex` to 1 and in the next loop compare MONOM 1 and MONOM 4. – Ingo Leonhardt Jul 19 '13 at 14:58
  • @Ingo, If they have the same power I want it to sum their coefficients, if their power is different I want the power index to advance. This should works since the function gets the array already sorted by powers. – Quaker Jul 19 '13 at 15:01
  • 1
    I don't think so. Every time you find a different power then the one of the previous MONOM you should set `powerIndex` to the index of that new MONOM not just ++. Or you have to shrink your array immediately whenever you find a MONOM with the same power then the one before. – Ingo Leonhardt Jul 19 '13 at 15:05

1 Answers1

1

I assume outside sumMonomsWithSamePower() you have allocated polynomial with something like polynomial = malloc( size * sizeof(MONOM) ); (everything else wouldn't be consistant to your realloc()). So you have an array of MONOMs and the memory location of polynomial[1] is polynomial[0] + sizeof(MONOM) bytes.

But now look at polynomial in sumMonomsWithSamePower() In the following paragraph I will rename it with ppoly (pointer to polynomial) to avoid confusing it with the original array: here it is a MONOM **, so ppoly[1] addresses the sizeof(MONOM *) bytes at the memory location ppoly[0] + sizeof(MONOM *) and interpretes them as pointer to a MONOM structure. But you have an array of structs, not an array of pointers. Replace your expressions by (*ppoly)[i].power (and all the others accordingly of course) and that part will work. By the way that's excactly the difference of the two debugger statements you have mentioned.

Besides, look at my comments concerning the use of powerIndex

Ingo Leonhardt
  • 9,435
  • 2
  • 24
  • 33