我已经在一行代码上工作了三天,我发现它似乎没有像我想象的那样分配内存。
我有一个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个字节,这对于我测试的所有w
和h
都是固定的,这不是我想的。以w=5, h=5
为例,数组的大小应为 5 * 5 * 8 。
对于像这样分配的内存,film._width
将被修改
当w
和h
都设置为1
时,内存会被意外“正确”分配:
0x7f90b9d00000
0x7f90b9d00010
0x7f90b9d00020
答案 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
的内容。