1

I'm having an issue with some code that I'm writing; Whenever I delete the array that I've dynamically allocated my program crashes and throws an error that says "_BLOCK_TYPE_IS_VALID (phead- nblockuse)".

class Shape 
{
protected:
    unsigned int numberOfVertices;
    glm::vec2 *vertexCoords; //openGL 2d vector..

public:
    Shape();
    virtual ~Shape() {}
}

class Rectangle : public Shape
{
protected:
    unsigned int width;
    unsigned int height;

    void initVertexCoords();

public:
    Rectangle();
    Rectangle( unsigned int tempWidth, unsigned int tempHeight );
    ~Rectangle();
}

Rectangle::Rectangle( unsigned int tempWidth, unsigned int tempHeight )
{
    width = tempWidth;
    height = tempHeight;

    initVertexCoords();
}

void Rectangle::initVertexCoords()
{
    numberOfVertices = 4;

    vertexCoords = new glm::vec2[ numberOfVertices ];    //Dynamic allocation..

    vertexCoords[0].x = -width * 0.5f;
    vertexCoords[0].y = -height * 0.5f;

    vertexCoords[1].x = -width * 0.5f;
    vertexCoords[1].y = height * 0.5f;

    vertexCoords[2].x = width * 0.5f;
    vertexCoords[2].y = height * 0.5f;

    vertexCoords[3].x = width * 0.5f;
    vertexCoords[3].y = -height * 0.5f;
}

Rectangle::~Rectangle()
{
    delete [] vertexCoords; //freeing of dynamically allocated array..
    //program doesn't crash when this destructor is empty!
}

So, a pointer to a 2D vector is created in Shape (the parent class), and the constructor of the subclass, Rectangle, dynamically allocates an array and stores the address of the first element in that pointer.

However, the program throws a runtime default exception [_BLOCK_TYPE_IS_VALID (phead- nblockuse)] when I try to delete that array in the Rectangle's destructor. When I remove the delete command from the destructor, the program compiles and runs fine. However, I'm concerned about the possibility of memory leaks; and I'd like to learn how to dynamically allocate objects and arrays of objects correctly. I've looked this up for about 2 hours now and I still haven't been able to find a solution.

I assumed that a call to 'new' dynamically allocates a certain amount of memory on the heap and would eventually require that memory to be freed by a call to 'delete'. It stands to reason that something that is allocated within the class constructor (or, in this case, in a class method which is called inside the constructor) should be freed within the class destructor..

I'm still new to C++ and programming in general, so there may be something very simple that I'm overlooking. Please let me know if there is a glaring error in my code that would cause this kind of error.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
MrKatSwordfish
  • 1,504
  • 5
  • 18
  • 30
  • 3
    possible duplicate of [What is The Rule of Three?](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – juanchopanza Jun 02 '13 at 07:19
  • 2
    Obvious [rule of three](http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29) violation. – David Schwartz Jun 02 '13 at 07:19
  • This code is wrong in too many respects. (1) Public data members (2) Non-virtual destructors (3) Child class mucking with parent's data members (4) Raw pointers (5) Raw legacy arrays (6) (not shown in the snippet but can be guessed) Passing polymorphic objects by value. (7) Last but not least, the already mentioned Rule Of Three violation. Given enough luck you could get away with any of those, but it is not recommended. Consider picking a good C++ book. – n. m. could be an AI Jun 02 '13 at 08:38
  • 1
    @n.m. There are clearly problems here, but (1) isn't necessarily wrong, (2) isn't the case in the snippet, and doing (4) and (5) is a way of taking unnecessary risk, but it's not wrong as such. – jogojapan Jun 02 '13 at 09:15
  • 1
    @MrKatSwordfish Actually, yes, the rule of three is likely to be an important part of the solution. If you don't define the copy constructor / assignment operator properly, the default implementation will make a shallow copy of the pointer. When the copied object is destroyed, the destructor will call `delete []` on that pointer, and when the original object is destroyed, the destructor will call `delete []` again, still on the same pointer. So you need to ensure that a deep copy is made when copying. – jogojapan Jun 02 '13 at 09:26
  • @jogojapan: (2) was there back then. (1)-(7) are not *necessarily* wrong, just close enough to be wrong for all practical purposes. – n. m. could be an AI Jun 02 '13 at 10:07
  • Probably doesn't help, but please do not use raw pointers! There are classes like unique_ptr that make your code much easier (e.g. see rule of five). – Werner Henze Jul 10 '15 at 09:40

0 Answers0