Search code examples
c++memorymemory-managementnew-operator

c++ Memory allocated wrong?


I've been working on a single line of code for three days and I found out it seems the memory allocated not as I supposed.

I have a Buffer class which owns two int variables and a *float pointer, which I think takes up 16 bytes in memory.

I also have a Film class which holds two int variables, two Vec3f variables, and a Buffer* pointer. Vec3f is a class which holds three float variables.

Class definitions are as follows:

class Buffer {
    public:
        int _width;
        int _heigth;
        Vec3f *_data;

        Buffer(int w, int h) : _width(w), _height(h) {
            _data = new Vec3f(_width*_heigth);
        }
        ~Buffer();
    };

struct Film {
        int _width;
        int _height;
        Vec3f _left_bottom_corner;
        Vec3f _left_up_corner;
        Buffer *_cbuffer;

        Film(int w, int h, Buffer *cbuffer) : _width(w), _height(h), _cbuffer(cbuffer) {}   
};

template<typename ElementType, unsigned Size>
    class Vector {
    private:
        std::array<ElementType, Size> _v;
};
typedef Vector<float, 3> Vec3f;

And I initialize them like this:

int w = 5; int h = 5;
Buffer *b = new Buffer(w, h);
Film *film = new Film(w, h, b);

Something weird happened when I tried to assign values to film->_cbuffer->data[i] so I debugged the program

std::cout << b << std::endl;
std::cout << b->_data << std::endl;
std::cout << film << std::endl;

and the output is

0x7fa500500000
0x7fa500600000
0x7fa500600010

I think a Buffer instance should take up 16 bytes and a Film instance should take up to 4*2 + 4*3*2 + 8 bytes. But what really matters is the size of Buffer._data array, which I allocated manually with new operator.

From the given result the array takes up to 16 bytes and this is fixed for all w and h I've tested and this is not what I suppose. Take w=5, h=5 for example, the size of the array should be 5 * 5 * 8 .

For the memory allocated like this, film._width would be modified when When w and h are both set to 1, the memory is allocated "right" accidentally:

0x7f90b9d00000
0x7f90b9d00010
0x7f90b9d00020

Solution

  • new Vec3f(_width*_heigth) doesn't initialize any array of variable length. The size of Vec3f array field is always 3, and this is probably not what you want in your buffer constructor. BTW, you don't have any Vector::Vector(some_kind_of_int) constructor at all.

    Probably you want to use (runtime-known size) std::vector in your buffer instead of something based on (compiletime-known constant (AKA constexpr) length) std::array.