1

I will simplify the problem in order to present a minimal and reproducible example:

I have a class Polynomial which is just a wrapper around an array of coefficients. For convenience in my analyses downstream it is a good idea to write it as a template regarding to the max. degree it can represent. Please remember that an N-th degree polynomial will hold N+1 coefficients.

template <const unsigned int MaxDeg>
class Polynomial {

  public:

    int *coefficients;

    Polynomial(int* arr) {
        coefficients = new int[MaxDeg+1];
        for (unsigned int i=0; i <= MaxDeg; i++) coefficients[i] = arr[i];
    }

    Polynomial() {
        coefficients = new int[MaxDeg+1]();
    }

    ~Polynomial() {
        delete[] coefficients;
    }

    int& operator[](int index) const {
        return coefficients[index];  
    }
};

In my main I test the code with creating one polynomial and then a one-sized array for it:

    int f_q[] = {5, 9, 6, 16, 4, 15, 16, 22, 20, 18, 30};
    Polynomial<10> P_f_q(f_q);
    Polynomial<10> P_arr[1] = {P_f_q}; // this line raises error

I get the following memory error:

test(33770,0x10de6be00) malloc: *** error for object 0x7fef43605420: pointer being freed was not allocated
test(33770,0x10de6be00) malloc: *** set a breakpoint in malloc_error_break to debug
[1]    33770 abort      ./test

In reality my code is much more complex but I commented out as much as I could and I really can't see where does the error come from(?)

Jeffrey
  • 11,063
  • 1
  • 21
  • 42
maciek
  • 1,807
  • 2
  • 18
  • 30
  • You need to provide a copy constructor (and copy assignment operator). The compiler created one is not good when you are doing manual memory management. – Yksisarvinen Jun 20 '21 at 16:11
  • 3
    Specifically, the default copy constructor results in two objects sharing coefficients, and thus a double deletion. – Jeffrey Jun 20 '21 at 16:12
  • Ah, OK. But where is a copy constructor called here? `Polynomial<10> P_arr[1] = {P_f_q};` – maciek Jun 20 '21 at 16:13
  • @maciek, Probably, here is where the copy constructor is called in your code "Polynomial<10> P_f_q(f_q);" – Job_September_2020 Jun 20 '21 at 16:14
  • How do you expect something from `p_f_q` to wind up in a completely different object without copying it, at some point along the way? – Sam Varshavchik Jun 20 '21 at 16:14
  • 1
    @maciek, The first thing is that you need to define a copy constructor. The second thing is that you should also define (overload) a copy assignment operator=. Here is where you use the copy assignment in your code "Polynomial<10> P_arr[1] = {P_f_q};" (But, it seems you have not defined the copy assignment either.) – Job_September_2020 Jun 20 '21 at 16:17
  • This is why on your previous question I suggested making `coefficients` a `std::vector` instead of an `int*`. Although if you're going to template on `MaxDeg` thus you always know the size of the container you're allocating at compile time, you could use a `std::array`. – Nathan Pierson Jun 20 '21 at 16:20
  • @maciek `int main() { int a[] = {1}; Polynomial p1(a); Polynomial p2 = p1; }` -- If this simple program can cause all havoc, it's time to investigate your `Polynomial` class and write it so that *all* copy situations are working correctly before using `Polynomial` any further. – PaulMcKenzie Jun 20 '21 at 18:32

0 Answers0