c ++内存分配错了?

时间:2018-03-17 13:50:41

标签: 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;

我将它们初始化为:

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

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

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

,输出

0x7fa500500000
0x7fa500600000
0x7fa500600010

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

从给定的结果来看,数组最多需要16个字节,这对于我测试的所有wh都是固定的,这不是我想的。以w=5, h=5为例,数组的大小应为 5 * 5 * 8

对于像这样分配的内存,film._width将被修改 当wh都设置为1时,内存会被意外“正确”分配:

0x7f90b9d00000
0x7f90b9d00010
0x7f90b9d00020

2 个答案:

答案 0 :(得分:5)

你在这里看不到问题吗?

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

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

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

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

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

如果您要查看_data对象中Buffer的地址,则应为

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

答案 1 :(得分:2)

new Vec3f(_width*_heigth)不会初始化任何可变长度数组。 Vec3f数组字段的大小始终为3,这可能不是您想要的缓冲区构造函数。顺便说一句,你根本没有任何Vector::Vector(some_kind_of_int)构造函数。

您可能希望在缓冲区中使用(运行时已知大小)std::vector而不是基于(compiletime-known constant(AKA constexpr)长度)std::array的内容。