简体   繁体   中英

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

Do you not see a problem here?

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

Is it not strange that uninitialized _width and _heigth used? Probably you want:

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

The line below outputs the address of Vec3f array pointed by _data .

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

If you are going to look at the address of _data within the Buffer object, it should be

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

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM