Home > Back-end >  Errоr: Invalid address specified to RtlValidateHeap
Errоr: Invalid address specified to RtlValidateHeap

Time:10-04

I am making a program that checks if stacks are equаl.

With this code, I am getting an error:

HEAP[ldf.exe]: Invalid address specified to RtlValidateHeap

It works until returning answer in func equal_stacks, so maybe a problem has to do something with deleting stacks that he gets when function starts?

Destructor was written by my teacher, so it is probably right. Maybe a problem is somewhere in equals_stacks function?

#include <iostream>

template<typename T>
class stackm{
    int capacity;
    int count;
    T* data;
public:
    stackm();
    ~stackm();
    void push(const T& elem);
    void push(T&& elem);
    void pop();
    T& top();
    const T& top() const;
    int size() const;
};

template<typename T>
stackm<T>::stackm() {
    capacity = 1;
    count = 0;
    data = new T[1];
}

template<typename T>
stackm<T>:: ~stackm() {
    delete[] data;
}

template<typename T>
void stackm<T>::pop() {
    --count;
}

template <typename T>
void stackm<T>::push(const T& elem) {
    if (this->count == this->capacity) {
        size_t new_capacity = capacity * 2;
        T* new_data = new T[new_capacity];
        for (size_t i = 0; i < this->capacity;   i) {
            new_data[i] = std::move(this->data[i]);
        }
        delete[] this->data;
        this->capacity = new_capacity;
        this->data = new_data;
    }
    data[count  ] = elem;
}

template <typename T>
void stackm<T>::push(T&& elem) {
    if (this->count == this->capacity) {
        size_t new_capacity = capacity * 2;
        T* new_data = new T[new_capacity];
        for (size_t i = 0; i < this->capacity;   i) {
            new_data[i] = std::move(this->data[i]);
        }
        delete[] this->data;
        this->capacity = new_capacity;
        this->data = new_data;
    }
    data[count  ] = elem;
}

template <typename T>
int stackm<T>::size() const {
    return count;
}

template <typename T>
T& stackm<T>::top() {
    return data[count - 1];
}

template <typename T>
const T& stackm<T>::top() const {
    return data[count - 1];
}

template<typename Stack>
bool equal_stacks(Stack s1, Stack s2) {
    if (s1.size() != s2.size()) {
        return false;
    }
    while (s1.size() != 0) {
        if (s2.top()  != s1.top()) {
            return false;
        }
        s1.pop();
        s2.pop();
    }
    return true;
}

int main() {
    stackm<int> stac1 = stackm<int>();
    stackm<int> sd23 = stackm<int>();
    sd23.push(23);
    sd23.push(45);
    std::cout << equal_stacks<stackm<int>>(stac1, sd23);
}

CodePudding user response:

You have delete[] data; in line 26 and delete data; in line 39. data is an array, so you delete it with delete[] only.

And you never use new_data anywhere. You probably want to assign it to data after line 39.

Also note that you have written a custom destructor, so you should follow the rule of 5 and specify how your class shall behave in case of copy constructor, copy assignment, move constructor and move assignment.

You also want to learn how to debug small programs.

CodePudding user response:

I solved it by passing values to function by reference

#include <iostream>
template<typename T>
class stackm{
    int capacity;
    int count;
    T* data;
public:
    stackm();
    ~stackm();
    void push(const T& elem);
    void push(T&& elem);
    void pop();
    T& top();
    const T& top() const;
    int size() const;
};

template<typename T>
stackm<T>::stackm() {
    capacity = 1;
    count = 0;
    data = new T[1];
}
template<typename T>
stackm<T>:: ~stackm() {
    delete[] data;
}
template<typename T>
void stackm<T>::pop() {
    --count;
}
template <typename T>
void stackm<T>::push(const T& elem) {
    if (this->count == this->capacity) {
        size_t new_capacity = capacity * 2;
        T* new_data = new T[new_capacity];
        for (size_t i = 0; i < this->capacity;   i) {
            new_data[i] = std::move(this->data[i]);
        }
        delete[] this->data;
        this->capacity = new_capacity;
        this->data = new_data;
    }
    data[count  ] = elem;
}

template <typename T>
void stackm<T>::push(T&& elem) {
    if (this->count == this->capacity) {
        size_t new_capacity = capacity * 2;
        T* new_data = new T[new_capacity];
        for (size_t i = 0; i < this->capacity;   i) {
            new_data[i] = std::move(this->data[i]);
        }
        delete[] this->data;
        this->capacity = new_capacity;
        this->data = new_data;
    }
    data[count  ] = elem;
}

template <typename T>
int stackm<T>::size() const {
    return count;
}

template <typename T>
T& stackm<T>::top() {
    return data[count - 1];
}

template <typename T>
const T& stackm<T>::top() const {
    return data[count - 1];
}

template<typename Stack>
bool equal_stacks(Stack &s1, Stack &s2) {
    Stack temp1 = Stack();
    Stack temp2 = Stack();
    if (s1.size() != s2.size()) {
        return false;
    }
    while (s1.size() != 0) {
        if (s1.top()  != s2.top()) {
            return false;
        }
        temp1.push(s1.top());
        temp2.push(s2.top());
        s1.pop();
        s2.pop();
    }
    while (s1.size() != 0) {
        temp1.push(s1.top());
        s1.pop();
    }
    while (s2.size() != 0) {
        temp2.push(s1.top());
        s2.pop();
    }
    while (temp1.size() != 0) {
        s1.push(temp1.top());
        temp1.pop();
    }
    while (temp2.size() != 0) {
        s2.push(temp2.top());
        temp2.pop();
    }
    return true;
}

I decided not to follow advice of WhozCraig and implement rulе of 3/5/0, because code of stack was given to me by teacher and i think i am not supposed to change it.

  •  Tags:  
  • c
  • Related