Reputation: 122
When I'm using a pointer to an instance to this class, for some reason it crashes when it comes to the destructor. It works when I'm not using pointers
The weirdest part is that it works in VC Code but not in Visual Studio.
Polynomial.h
class Polynomial {
private:
int32_t* coeffs;
uint32_t deg;
public:
Polynomial(int32_t* setCoeffs, uint32_t setDeg) {
deg = setDeg;
while (setCoeffs[deg] == 0 && deg > 0) deg--;
coeffs = new int32_t[deg + 1]();
for (uint32_t i = 0; i <= deg; i++) {
coeffs[i] = setCoeffs[i];
}
}
~Polynomial () {
delete[] coeffs;
}
std::string str() {
std::string out = "";
for (uint32_t i = deg; i > 0; i--) {
if (coeffs[i] == 0) continue;
if (coeffs[i] > 0 && i != deg) out += "+";
if (coeffs[i] != 1)
out += std::to_string(coeffs[i]);
if (i == 1) out += "x";
else if (i > 1) out += "x^" + std::to_string(i);
}
if (coeffs[0] != 0) {
if (coeffs[0] > 0) out += "+";
out += std::to_string(coeffs[0]);
}
return out;
}
friend std::ostream& operator<<(std::ostream& out, Polynomial p) {
out << p.str();
return out;
}
};
main.cpp
#include <iostream>
#include "Polynomial.h"
int main(){
int32_t* coeffs = new int32_t[3]();
coeffs[0] = 5;
coeffs[1] = 4;
coeffs[2] = 3;
Polynomial* p = new Polynomial(coeffs, 2);
std::cout << (*p);
delete p;
return 0;
}
I'm guessing it's something to do with the Visual Studio properties but I don't know what to change.
Upvotes: 1
Views: 119
Reputation: 51874
Your overload of the <<
operator takes its argument by value; so, in the line, std::cout << (*p);
a copy of *p
is made and, when the output is done, that copy is destroyed. However, as pointed out in the comments, you haven't implemented a proper copy constructor, so the compiler provides a default, which simply copies the data members' values (including the int32_t* coeffs
pointer member).
So, when the output operation is done, and the copy is destroyed, the memory pointed-to by coeffs
is deleted; then, when you come to delete the original, you are trying to delete that same memory a second time – hence the crash.
To fix the issue either: (a) implement proper copy and assignment constructors, which make real copies of the coeffs
data; or (b) give the argument to your <<
operator by reference, as follows:
friend std::ostream& operator<<(std::ostream& out, Polynomial& p) { // Pass "p" BY REFERENCE
out << p.str();
return out;
}
Of course, making the '(b)' change doesn't (shouldn't) mean that you can't also implement '(a)'. You should really do both; here's a likely implementation of the copy constuctor:
Polynomial(const Polynomial& rhs) {
deg = rhs.deg;
coeffs = new int32_t[deg + 1];
for (uint32_t i = 0; i <= deg; i++) {
coeffs[i] = rhs.coeffs[i];
}
}
Upvotes: 2