c ++内存分配错了?

jin*_*lei 0 c++ memory memory-management new-operator

我已经在一行代码上工作了三天,我发现它似乎没有像我想象的那样分配内存.

我有一个Buffer拥有两个int变量和一个*float指针的类,我认为它占用了16个字节的内存.

我还有一个Film包含两个int变量,两个Vec3f变量和一个Buffer*指针的类.Vec3f是一个包含三个float变量的类.

类定义如下:

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;
Run Code Online (Sandbox Code Playgroud)

我将它们初始化为:

int w = 5; int h = 5;
Buffer *b = new Buffer(w, h);
Film *film = new Film(w, h, b);
Run Code Online (Sandbox Code Playgroud)

当我尝试分配值时发生了一些奇怪的事情,film->_cbuffer->data[i]所以我调试了程序

std::cout << b << std::endl;
std::cout << b->_data << std::endl;
std::cout << film << std::endl;
Run Code Online (Sandbox Code Playgroud)

而输出是

0x7fa500500000
0x7fa500600000
0x7fa500600010
Run Code Online (Sandbox Code Playgroud)

我认为一个Buffer实例应该占用16个字节,一个Film实例应该占用4*2 + 4*3*2 + 8个字节.但真正重要的是Buffer._data数组的大小,我手动用new运算符分配.

从给定的结果来看,该数组最多需要16个字节,这对所有人都是固定的w,h我已经测试过,这不是我想的.采取w=5, h=5例如,阵列的大小应为5*5*8.

对于像这样分配的内存,film._width当When wh都被设置为时,将被修改1,内存被意外地"分配":

0x7f90b9d00000
0x7f90b9d00010
0x7f90b9d00020
Run Code Online (Sandbox Code Playgroud)

S.M*_*.M. 5

你在这里看不到问题吗?

Buffer(int w, int h) {
   _data = new Vec3f(_width*_heigth);
}
Run Code Online (Sandbox Code Playgroud)

未经初始化_width_heigth使用并不奇怪吗?可能你想要:

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

下面的行输出Vec3f指向的数组的地址_data.

std::cout << b->_data << std::endl;
Run Code Online (Sandbox Code Playgroud)

如果你要查看对象_data内的地址Buffer,它应该是

std::cout << &b->_data << std::endl;
Run Code Online (Sandbox Code Playgroud)