0

I'm trying to implement Vector in C++ and I faced a memory problem delete the array. This is my code:

template<class T>
class Vector {
    T* _vector;
    size_t _size;
    size_t _capacity;
public:
    Vector() : _vector(nullptr), _size(0), _capacity(0) {};
    Vector(const int &capacity) : _capacity(capacity) {
        _vector = (T*)malloc(capacity * sizeof(T));
    }

    Vector<T>& pushBack(const T &t) {
        _size++;
        if (_capacity >= _size)
            _vector[_size - 1] = t;
        else {
            _capacity <<= 1;
            _vector = (T*)realloc(_vector, _size * sizeof(T));
            _vector[_size - 1] = t;
        }
        return *this;
    }

    virtual ~Vector() { delete[] _vector; }
};

I tried to do a fluent programming in order to be able making this in main:

int main() {
    Vector<int> v();
    v.pushBack(42).pushBack(100);
}

after debugging this I noticed that the fluent programming cause the destructor HEAP CORRUPTION ERROR, anyone knows why?

Also, is there a better "C++" way to realloc the T array?

Thanks!

EDIT: I changed all malloc/realloc functions in the class to new T[size] and now it's o.k.

Elad Aharon
  • 405
  • 2
  • 18
  • you code doesn't compile as it is. – Jack Jan 13 '19 at 14:19
  • Don’t use `realloc` (or `malloc` or `free`) in C++. You can only `delete []` what you got from `new []`. – molbdnilo Jan 13 '19 at 14:21
  • Why are you trying to reinvent the wheel? – πάντα ῥεῖ Jan 13 '19 at 14:27
  • You forgot to initialise `_size` in one constructor. And passing `int` by const reference is a pessimisation. – molbdnilo Jan 13 '19 at 14:29
  • 1
    This is only a programming exercise. I'm not trying to reinvent something I want to know how the data structures work from the inside @πάνταῥεῖ – Elad Aharon Jan 13 '19 at 14:29
  • @molbdnilo Thank you, but still there is the heap corruption bug related to the pushBack() function. Also you can absolutely write "delete ptr" if ptr was allocated with malloc, this is not the problem. – Elad Aharon Jan 13 '19 at 14:33
  • @EladAharon: No you can't - it's undefined behavior. See [here](https://stackoverflow.com/questions/10854210/behaviour-of-malloc-with-delete-in-c) – R_Kapp Jan 13 '19 at 14:37
  • 1
    @EladAharon: you can't delete ptr if's allocated by std::malloc (or std::realloc). The former takes care of destruction (and should be used with new[]) while the latter doesn't. You are mixing two kinds of allocators. You need to be consistent (and possibly use only C++ new/delete since you could hide problems when working with int but not with a non trivial object). – Jack Jan 13 '19 at 14:37
  • 1
    @EladAharon *if ptr was allocated with malloc* -- And if `T` was a `std::string`, the whole thing falls apart using `malloc`. Before delving into this, you should learn a few more things about proper heap management in C++, and what the [rule of 3](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) is about. – PaulMcKenzie Jan 13 '19 at 14:43
  • `Vector v();` -- This does not create an object. This declares a function call `v` that takes no arguments and returns a `Vector`. – PaulMcKenzie Jan 13 '19 at 14:44
  • @Jack Thank you! I changed pushBack() to allocate a new T *vector; copied the elements and then delete[] _vec, also very useful link :) – Elad Aharon Jan 13 '19 at 14:46
  • @EladAharon Why are you setting `capacity` to 0 in the default constructor? This `_capacity <<= 1;` will not increase capacity if you start at 0. – PaulMcKenzie Jan 13 '19 at 14:50
  • 1
    @EladAharon There is no equivalent to `realloc` when using `new[]` in C++. You have to 1) Allocate new memory. 2) Copy the old contents to the new memory. 3) Delete the old memory 4) Assign the pointer to the new memory. So your implementation is not enough. – PaulMcKenzie Jan 13 '19 at 15:05
  • 1
    Crashes on my machine, because the `malloc/free` heap is separate from the `new/delete` heap, which is separate rom the `new[]/delete[]` heap on my machine. (Which is intentional, so as to help detect when someone is conflating the various allocation operations, which is UB.) – Eljay Jan 13 '19 at 15:06
  • "Also, is there a better "C++" way to realloc the T array?" Yes, C++ has `std::vector` which handles resizing. – Eljay Jan 13 '19 at 15:09
  • @EladAharon *I want to know how the data structures work from the inside* -- There really are too many things going on that are incorrect. Rather than give a long, drawn out explanation, [see an example of a minimal, but working fake-vector class](http://coliru.stacked-crooked.com/a/f3c7be3fb0706cf6). – PaulMcKenzie Jan 13 '19 at 15:14

0 Answers0