我正在重新编写一个旧的循环缓冲区类,以使其更健壮。我在 T 类型的堆上分配一个缓冲区(因此该类是模板化的)。但是,我在释放资源时遇到问题,这可能是因为 T 是指向动态分配空间的指针。
简而言之,这是一个具有默认值参数的 ctor
template <typename T, unsigned int SIZE>
CircularBuffer(const T default_val) {
_buffer = new T[SIZE];
// assign each block default value, etc
}
// dtor
~CircularBuffer()
{
delete [] _buffer;
}
但是,例如有人决定这样做:
CircularBuffer<int*, 4> cb(new int); // buffer of 4, holding int*, with default value of new int
// later ~CircularBuffer call is made
// user allocated memory is not freed
我将如何能够(或让用户)释放此内存?我从用户的角度手动尝试过:
delete cb.at(0); // .at returns T& (so it would effectively return the pointer)
// above is access violation
我试图弄清楚如何在析构函数中执行此操作,但我无法执行任何类型的 delete _buffer[i] 因为编译器认为模板 T 不是指针(即使它可能是)。
我可以安全地处理这种情况,还是用户可以对此做些什么,这样责任就不是我的了(因为类没有在内部分配这个,所以用户是)?
编辑* * * 我刚刚意识到将 T* 作为模板参数传递时使用 new 进行的分配不会返回预期的缓冲区大小。
// call default ctor
CircularBuffer<double*, 2> cb(); // _buffer = new T[SIZE];
// sizeof(_buffer) == 4;
// sizeof(double*) == 4;
// sizeof(double*[2]) == 8; // _buffer should be this size, as it holds 2 4byte pointers, what happened?
我不确定我是否应该为此提出一个新问题,或者将它与原始问题一起留在这里,但我认为这解释了我之前遇到的一些访问冲突(在尝试取消引用上述实例的 _buffer[1] 之后。不幸的是我不知道是什么原因造成的。