1
Debug Assertion Failed!

Program: ...nts\Visual Studio 2015\Projects\Project 5\Debug\Project 5.exe
File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp
Line: 892

Expression: is_block_type_valid(header->_block_use)

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)

The program runs and outputs everything correctly, and throws this error. I haven't been able to find any good explanations of what this means or how to go about finding or fixing it. Here is a complete copy of the (incredibly ugly and badly written) code:

#include <iostream>
using namespace std;

/* a class for storing a Binary Tree */
template <class Type>
class BinaryTree {
protected:
    Type parentArray[10];
    Type childArray[10];
public:
    BinaryTree();
    BinaryTree(int& k);
    ~BinaryTree();
    BinaryTree(BinaryTree<Type>& bt);
    void operator= (BinaryTree<Type>& bt);
    friend ostream& operator<< (ostream& s, BinaryTree<Type> bt) {
        s << "[ ";
        bt.inorder(bt.getRoot());
        s << "]" << endl;
        return s;
    };
    int size();
    int height();
    int getLeft(int k);
    int getRight(int k);
    void preorder(int k);
    void inorder(int k) {

        // do I have a left child?
        if ((getLeft(k)) != -1) {
            // if yes inorder (left child)
            inorder(getLeft(k));
        };
        // output k
        cout << k << " ";
        // do I have a right child?
        if ((getRight(k)) != -1) {
            // if yes inorder (right child)
            inorder(getRight(k));
        };
    };
    void postorder(int k);
    void setRoot(Type& val);
    void setParent(Type* child, Type* parent);
    void setLeft(Type& val);
    void setRight(Type& val);
    int getRoot();
};

/* default constructor */
template <class Type>
BinaryTree<Type>::BinaryTree() {
    parentArray = new ArrayClass<Type>();
    childArray = new ArrayClass<Type>();
};

/* non-empty constructor */
template <class Type>
BinaryTree<Type>::BinaryTree(int& k) {
//  parentArray = new Type[k];
//  childArray = new Type[k];
};

template <class Type>
BinaryTree<Type>::~BinaryTree() {
    delete[] parentArray;
    delete[] childArray;
};

template <class Type>
BinaryTree<Type>::BinaryTree(BinaryTree<Type>& bt) {
    for (int i = 0; i < bt.size(); i++) {
        parentArray[i] = bt.parentArray[i];
        childArray[i] = bt.childArray[i];
    };
};

template <class Type>
void BinaryTree<Type>::operator= (BinaryTree<Type>& bt) {

};


/* return the size of the tree using the length of the parent array */
template <class Type>
int BinaryTree<Type>::size() {

    return (sizeof(parentArray)/sizeof(*parentArray));
};


template <class Type>
int BinaryTree<Type>::height() {
    return 5;
};

template <class Type>
int BinaryTree<Type>::getLeft(int k) {

    // if the parent array value of the given number is k and 
    // the child array value indicates it is a left child
    for (int i = 0; i < size(); i++) {
        if ((parentArray[i] == k) && (childArray[i] == 0)) {

            // return that value
            return i;
        };
    };
    return -1;
};

template <class Type>
int BinaryTree<Type>::getRight(int k) {

    // if the parent array value of the given number is k and 
    // the child array value indicates it is a right child
    for (int i = 0; i < size(); i++) {
        if ((parentArray[i] == k) && (childArray[i] == 1)) {

            // return that value
            return i;
        };
    };
    return -1;
};

template <class Type>
void BinaryTree<Type>::preorder(int k) {
    // output k
    cout << k << " ";
    // do I have a left child?
    if ((getLeft(k)) != -1) {
        // if yes preorder left child
        preorder(getLeft(k));
    };
    // do I have a right child?
    if ((getRight(k)) != -1) {
        // if yes preorder right child
        preorder(getRight(k));
    };
};

template <class Type>
void BinaryTree<Type>::postorder(int k) {
    // do I have a left child?
    if ((getLeft(k)) != -1) {
        // if yes inorder (left child)
        inorder(getLeft(k));
    };
    // do I have a right child?
    if ((getRight(k)) != -1) {
        // if yes inorder (right child)
        inorder(getRight(k));
    };
    // output k
    cout << k << " ";
};

template <class Type>
void BinaryTree<Type>::setRoot(Type& val) {
    // if the given value is the root of the tree then set
    // its index in the parent and child arrays to -1
    parentArray[val] = -1;
    childArray[val] = -1;
};

template <class Type>
void BinaryTree<Type>::setParent(Type* child, Type* parent) {

    // set a given value as the parent of a given value
    parentArray[(*child)] = *parent;
};

template <class Type>
void BinaryTree<Type>::setLeft(Type& val) {

    // set a given value in the child array to indicate a left child
   childArray[val] = 0;
};

template <class Type>
void BinaryTree<Type>::setRight(Type& val) {

    // set a given value in the child array to indicate a right child
    childArray[val] = 1;
};

template <class Type>
int BinaryTree<Type>::getRoot() {

    // find the root value of the tree
    for (int i = 0; i < size(); i++) {
        if (parentArray[i] == -1) {

            // and return it
            return i;
        };
    };
};

int  main() {
    int* val1 = new int;
    int* val2 = new int;
    int* val3 = new int;
    int count;

    cin >> count;

    BinaryTree<int> bt(count);

    for (int i = 0; i < count; i++) {
        cin >> *val1;
        cin >> *val2;
        cin >> *val3;

        if (i == 0) {
            bt.setRoot(*val1);
        };

        if (*val2 != -1) {
            bt.setParent(val2, val1);
            bt.setLeft(*val2);
        }
        if (*val3 != -1) {
            bt.setParent(val3, val1);
            bt.setRight(*val3);
        }

        val1 = new int;
        val2 = new int;
        val3 = new int;
    };

    cout << bt.size() << endl;
    bt.postorder(bt.getRoot());
    cout << endl;
    bt.preorder(bt.getRoot());
    cout << endl;

    delete val1;
    delete val2;
    delete val3;
};

Some of the functions in the BinaryTree class aren't finished yet and just have filler garbage in them for testing.

WMS
  • 41
  • 1
  • 3
  • 8
  • The `for` loop in `main` is leaking memory. `val1`, `val2` `val3` are new'd at the bottom of the loop but never freed. – Richard Critten Apr 13 '16 at 00:23
  • Recommendation: Test more frequently or Write smaller chunks of code before testing. When testing one function's worth of new code it's usually real easy to figure out where the bug is. Write constructor and destructor and test. Add a method. Test. Add another method and test. Rinse. Repeat. – user4581301 Apr 13 '16 at 00:23
  • Does this answer your question? [Why do I get \_CrtIsValidHeapPointer(block) and/or is\_block\_type\_valid(header->\_block\_use) assertions?](https://stackoverflow.com/questions/64418624/why-do-i-get-crtisvalidheappointerblock-and-or-is-block-type-validheader-b) – ead Oct 22 '20 at 10:09

1 Answers1

2

Your BinaryTree destructor always makes sure to:

delete[] parentArray;
delete[] childArray;

Unfortunately, one of the class's constructors does not new any of these arrays. As such, the destructor ends up attempting to delete a pair of uninitialized garbage pointers.

It's also possible that this class violates the Rule Of The Three, but I have not analyzed this sufficiently.

EDIT: as it's been pointed out in the comments, these are not pointers; so this is wrong anyway, but for other reasons.

Community
  • 1
  • 1
Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • 5
    Those arrays are not pointers. There is no need to `new` them. And they should not be deleted. – paddy Apr 13 '16 at 00:04