Reputation: 141
I am getting the following error
"HEAP CORRUPTION DETECTED: after Normal block (#271) at 0x0108C4A8. CRT detected that the application wrote to memory after end of heap buffer."
Background info
I am attempting to emulate inheritance,polymorphism, and dynamic method binding in c++ without actually using these features. I have a function thats emulating a constructor called 'Square_new(x,y,sidelen)' that calls new and returns a Square pointer. I then cast this to the parent class "Shape". I know that this code works
cout << "TESTING SQUARE" << endl;
cout << "Initializing Square at x=1,y=1,sidelength=5" << endl;
Shape* s2 = (Shape*)Square_new(1, 1, 5);
cout << "Expected area = 5*5 = 25" << endl << endl;
// later on in the code
delete s2;
However when I add the following code (above the delete invocation of course)
//Added Portion
Rectangle* r2 = (Rectangle*)s2;
Square* sq = (Square*)s2;
Here is the implementation of Square.cpp
void** vmtSquare;
Square* Square_new(double positionX, double positionY, double sidelength) {
Square* s = new Square;
Square_Square(s, positionX, positionY, sidelength);
s->vmt = vmtSquare;
return s;
}
void Square_Square(Square* _this, double positionX, double positionY, double sidelength) {
Rectange_Rectangle((Rectangle*)_this, positionX, positionY, sidelength, sidelength);
Square_createVMT;
}
// This resize will ovveride the rectangle resize
void Square_resizeA(Rectangle* _this, double width, double height) {
if (width == height) {
Rectangle_resize(_this, width, height);
}
}
// following two functions are extensions
void Square_resizeB(Square* _this, double sidelength) {
Rectangle_resize((Rectangle*)_this, sidelength, sidelength);
}
double Square_getSideLength(Square* _this) {
return Rectangle_getWidth((Rectangle*)_this);
}
void Square_Destructor(Square* _this) {
// The function doesnt do any thing but call
// parent destructor (Rectangle)
Rectangle_Destructor((Rectangle*)_this);
}
void Square_createVMT() {
// copy Rectangle vmt
vmtSquare = new void*[10];
vmtSquare[0] = (void*)Shape_getPositionX;
vmtSquare[1] = (void*)Shape_getPositionY;
vmtSquare[2] = (void*)Shape_move;
vmtSquare[3] = (void*)Rectangle_area;
vmtSquare[4] = (void*)Rectangle_Destructor;
vmtSquare[5] = (void*)Rectangle_getWidth;
vmtSquare[6] = (void*)Rectangle_getHeight;
//override rectangle resize and destructor
vmtSquare[4] = (void*)Square_Destructor;
vmtSquare[7] = (void*)Square_resizeA;
//extension methods
vmtSquare[8] = (void*)Square_resizeB;
vmtSquare[9] = (void*)Square_getSideLength;
}
Square in turn is 'derived' from rectangle, which is derived from Shape
// Rectangle.cpp
// Assignment 4 example
#include "Rectangle.h"
#include "Shape.h"
void** vmtRectangle;
Rectangle* Rectangle_new(double positionX, double positionY, double width, double height) {
Rectangle* r = new Rectangle;
Rectange_Rectangle(r, positionX, positionY, width, height);
r->vmt = vmtRectangle;
return r;
}
void Rectange_Rectangle(Rectangle* _this, double positionX, double positionY, double width, double height) {
//set fields for this Rectangle
_this->width = width;
_this->height = height;
Shape_Shape((Shape*)_this, positionX, positionY);
Rectangle_createVMT();
}
double Rectangle_getWidth(Rectangle*_this) {
return _this->width;
}
double Rectangle_getHeight(Rectangle* _this) {
return _this->height;
}
void Rectangle_resize(Rectangle* _this, double width, double height) {
_this->width = width;
_this->height = height;
}
double Rectangle_area(Shape* _this) {
Rectangle* r = (Rectangle*)_this;
return r->height * r->width;
}
void Rectangle_Destructor(Rectangle* _this) {
//doesnt do anything accept call parent's destructor
Shape_Destructor((Shape*)_this);
}
void Rectangle_createVMT() {
vmtRectangle = new void*[8];
//copy shapes vmt
vmtRectangle[0] = (void*)Shape_getPositionX;
vmtRectangle[1] = (void*)Shape_getPositionY;
vmtRectangle[2] = (void*)Shape_move;
vmtRectangle[3] = (void*)0;
vmtRectangle[4] = (void*)Shape_Destructor;
//overwrite area and destructor
vmtRectangle[3] = (void*)Rectangle_area;
vmtRectangle[4] = (void*)Rectangle_Destructor;
//extensions
vmtRectangle[5] = (void*)Rectangle_getWidth;
vmtRectangle[6] = (void*)Rectangle_getHeight;
vmtRectangle[7] = (void*)Rectangle_resize;
}
Here is Parent of Rectangle
// Shape.cpp
// Assignment 4 example
// Contains the definitions needed to emulate the Shape "class".
#include "Shape.h"
void Shape_Shape(Shape* _this, double positionX, double positionY)
{
_this->positionX = positionX;
_this->positionY = positionY;
}
double Shape_getPositionX(Shape* _this)
{
return _this->positionX;
}
double Shape_getPositionY(Shape* _this)
{
return _this->positionY;
}
void Shape_move(Shape* _this, double positionX, double positionY)
{
_this->positionX = positionX;
_this->positionY = positionY;
}
void Shape_Destructor(Shape* _this) {
//this function does absolutely nothing
//and is here for emulation purposes
}
void Shape_createVMT()
{
vmtShape = new void*[5];
vmtShape[0] = (void*) Shape_getPositionX;
vmtShape[1] = (void*) Shape_getPositionY;
vmtShape[2] = (void*) Shape_move;
// area() is abstract, so its entry in the VMT should be 0 (NULL).
vmtShape[3] = (void*) 0;
vmtShape[4] = Shape_Destructor;
}
Upvotes: 0
Views: 296
Reputation: 141
It turned out to be a super obscure error. The structs are supposed are used to represent classes. When Square is constructed it calls the rectangle constructor. However In order for this to work square must have the exact same fields as rectangle. I didn't post this in the code so there is no way anyone could have helped me (sorry for wasting your time) but anyway here it is now
Originally inside of Square.h and Rectangle.h
struct Square {
void** vmt;
//shape
double positionX;
double positionY;
};
struct Rectangle {
void** vmt;
//shape
double positionX;
double positionY;
//rectangle
double width;
double height;
};
When Square should have been defined as follows
struct Square {
void** vmt;
//shape
double positionX;
double positionY;
//rectangle
double width;
double height;
};
I still have no idea why this even matters so if anyone wants to commnent and explain I would be interested to know
Upvotes: 1