NeKon
NeKon

Reputation: 1

Reallocating memory but failing to properly handle free() causes crash

so i am doing a container on the raw pointers, and for some reason my program just started crashing on the free(data); line, why tf idk, how could something like this happen i also dont know, but the data on its own is valid and doesnt equal to newData, so it should me deletable, but it is actually not error message with debug mode on main function:

#include <iostream>
#include <cstdlib>
#include <cstring>
#include "RawBase.h"

int main() {
    RawVector<int> v;
    for (int i = 0; i < 100; i++) {
        v.push_back(i); // <- crashes here on second iteration
        v[i] += i;
    }
    for (int i = 0; i < v.get_size(); i++) {
        std::cout << v[i] << " ";
    }
    std::cout << std::endl;
}

actual class code:

#pragma once
#include <cstdlib>
#include <iostream>
#include <cstring>

template<typename T>
class RawVector {
private:
    T* data = nullptr;
    size_t size = 1;
    size_t capacity = 1;
    T* normalize_capacity() {
        while (capacity <= size) {
            capacity *= 2;
        }
        T* newData = (T*)realloc(data, sizeof(T) * capacity);
        if (!newData) {
            throw std::bad_alloc();
        }
        return newData;
    }
public:
    RawVector() {
        capacity = 2;
        data = (T*)calloc(1, sizeof(T));
    };
    void push_back(const T& elem) {
        try {
            if (capacity <= size) {
                auto newData = normalize_capacity();
                std::memcpy(newData, data, size * sizeof(T));
                std::cout << data[0] << std::endl;
                if (data != nullptr && newData != data) {
                    free(data);
                }
                data = newData;
            }
            data[size++] = elem;
        }
        catch (...) {
            std::cerr << "Something happened in push_back" << std::endl;
            throw;
        }
    }
    T& operator [] (const size_t index) {
        if (index >= size) {
            throw std::out_of_range("Index out of range");
        }
        return data[index];
    };

    const T& operator [] (const size_t index) const {
        if (index >= size) {
            throw std::out_of_range("Index out of range");
        }
        return data[index];
    }

    size_t get_size() const {
        return size;
    };
    size_t get_capacity() const {
        return capacity;
    };
};

tried many differents things to do, startig from checking if it is a nullptr, ending with checking difference between two variables

Upvotes: -4

Views: 131

Answers (0)

Related Questions