Rachel Higgs
Rachel Higgs

Reputation: 13

What is in unhandled error in c++ and how do I fix it?

I keep getting an "exception thrown" and "Unhandled exception" error on the last for loop of my code. I am not sure why this is happening, what it means, or how to fix it. The output won't even show up long enough for me to see if it is right. Any help would be appreciated.

The error says : Exception thrown at 0x00855AC9 in Final Project.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC. Unhandled exception at 0x00855AC9 in Final Project.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC.

class Geometry {
public:
    string color = "blue";
    void printColor() {
        cout << color << endl;
    }
    virtual void calArea() {
        cout << "Are: 0" << endl;
        cout << "Shape: Unknown" << endl;
    }
};

class Circle :public Geometry {
private:
    double radius;
    double area = 0;
public:
    Circle() {
        radius = 5.0;
    }
    void calArea() {
        area = 3.14 * radius * radius;
        cout << "Area: " << ", Shape: Circle, Radius: " << radius << endl;
    }
};

class Square :public Geometry {
private:
    double side;
    double area = 0.0;
public:
    Square() {
        side = 5.3;
    }
    void calArea() {
        area = side * side;
        cout << "Area: " << area << ", Shape: Sqaure, Side: " << side << endl;
    }

};

class Cube : public Geometry {
private:
    double length;
    double width;
    double height;
    double area;
public:
    Cube() {
        length = 4.0;
        width = 4.0;
        height = 4.0;
    }
    void calArea() {
        area = 6 * length * width;
        cout << "Area: " << ", Shape: Cube, Length: " << length << ", Width: " << width << ", Height: " << height << endl;
    }

};



int main()
{
    const int SIZE = 10;
    int i;

    Geometry* shapes[SIZE];
    for ( i = 0; i < SIZE; i++) {
        int choice = 1 + rand() % 3;
        if (choice == 1) {
            shapes[i] = new Circle();
        }

        else if (choice == 2) {
            shapes[i] = new Square();
        }
        
        else if (choice == 3) {
            shapes[i] = new Cube();
        }

        for (i = 0; i < SIZE; i++) {
            shapes[i]->calArea();
        }
    }
  

    return 0;
}

Upvotes: 1

Views: 1021

Answers (2)

Samuel Comeau
Samuel Comeau

Reputation: 56

You tryed to call shapes[i] for values of i=0 to 9. These values had not yet been assigned. So you are trying to access the shape at memory location which is not in the memory assigned to your application which should result in a segmentation fault. This is most likely from a missing bracket between your for statements.

Side Note: This would have been easier for you to diagnose if you used the programming convention of declaring temporary variables in the smallest scope. That is, if both of your for statements read

for(int i = 0; i < SIZE; i++) {

you would have recieved a meaningful error for trying to declare i twice and been able to fix the typo.

Upvotes: 0

prehistoricpenguin
prehistoricpenguin

Reputation: 6326

Your code has accessed uninitialized memory, the location 0xCCCCCCCC means uninitialized pointer in debug mode in visual studio

0xCC When the code is compiled with the /GZ option, uninitialized variables are automatically assigned to this value (at byte level).

I think the '}' needs to be put before the last loop, then all the pointers in the array have been inited. And it would be better to use std::vector here, my final code uses it.

    for ( i = 0; i < SIZE; i++) {
        int choice = 1 + rand() % 3;
        if (choice == 1) {
            shapes[i] = new Circle();
        }

        else if (choice == 2) {
            shapes[i] = new Square();
        }
        
        else if (choice == 3) {
            shapes[i] = new Cube();
        }

        for (i = 0; i < SIZE; i++) {
            shapes[i]->calArea();
        }
    }

Need to be change to:

    for ( i = 0; i < SIZE; i++) {
        int choice = 1 + rand() % 3;
        if (choice == 1) {
            shapes[i] = new Circle();
        }

        else if (choice == 2) {
            shapes[i] = new Square();
        }
        
        else if (choice == 3) {
            shapes[i] = new Cube();
        }
    }
    for (i = 0; i < SIZE; i++) {
        shapes[i]->calArea();
    }

After fixing, your code still has memory leaks. May consider using a smart pointer here. Since we have stored the base type's pointer, we need a virtual destructor to make sure that the memory to be corrected deleted.

For the rand() function, you need to call srand before using it to avoid always get the same random sequence for every run. And it's better to use random since c++11.

#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace std;

class Geometry {
 public:
  virtual ~Geometry() = default;
  string color = "blue";
  void printColor() { cout << color << endl; }
  virtual void calArea() {
    cout << "Are: 0" << endl;
    cout << "Shape: Unknown" << endl;
  }
};

class Circle : public Geometry {
 private:
  double radius;
  double area = 0;

 public:
  Circle() { radius = 5.0; }
  void calArea() {
    area = 3.14 * radius * radius;
    cout << "Area: " << area << ", Shape: Circle, Radius: " << radius << endl;
  }
};

class Square : public Geometry {
 private:
  double side;
  double area = 0.0;

 public:
  Square() { side = 5.3; }
  void calArea() {
    area = side * side;
    cout << "Area: " << area << ", Shape: Sqaure, Side: " << side << endl;
  }
};

class Cube : public Geometry {
 private:
  double length;
  double width;
  double height;
  double area;

 public:
  Cube() {
    length = 4.0;
    width = 4.0;
    height = 4.0;
  }
  void calArea() {
    area = 6 * length * width;
    cout << "Area: " << area << ", Shape: Cube, Length: " << length
         << ", Width: " << width << ", Height: " << height << endl;
  }
};

int main() {
  const int SIZE = 10;
  int i;

  std::vector<std::unique_ptr<Geometry>> shapes;
  for (i = 0; i < SIZE; i++) {
    int choice = 1 + rand() % 3;
    if (choice == 1) {
      shapes.emplace_back(new Circle());
    }

    else if (choice == 2) {
      shapes.emplace_back(new Square());
    }

    else if (choice == 3) {
      shapes.emplace_back(new Cube());
    }
  }

  for (auto& ptr : shapes) {
    ptr->calArea();
  }

  return 0;
}

Online demo

Upvotes: 3

Related Questions