调用线性化后奇怪的增强循环缓冲区行为
Strange boost circular buffer behaviour after calling linearize
我已经在我的 boost::circular_buffer
上实现了一个提取方法,它只是将 n
个元素复制到一个 destination
向量,然后从循环缓冲区中删除这 n 个元素(所以它更新内部指针,标记可以再次写入的位置):
void CircularBuffer::extract(const unsigned int n, vector<complex<float>> *destination){
// Wait until the buffer is not empty
std::unique_lock<mutex> l(lock);
notEmpty.wait(l, [this, n](){
return (int)(circularBuffer.size() - n) >= 0;
});
// We must copy n elements from a linearized version of the buffer
memcpy(destination, circularBuffer.linearize(), n);
// Remove extracted elements from circular buffer
circularBuffer.erase(circularBuffer.begin(), circularBuffer.begin() + n); //SIGSEGV
// Not full any more
notFull.notify_one();
}
当调用 erase
方法时,出现分段错误。
我使用以下尺码:
n = 9000
circularBuffer.size() = 9000 (at the moment when extract method is called)
circularBUffer.capacity() = 90000
但是,一旦 memcpy
行被执行,我猜是因为 linearize
调用,一切都乱七八糟,调试器显示:
circularBuffer.size() = 3238197033 (Hex: Hex:0xc102f729)
circularBUffer.capacity() = 18446744073434141805 (Hex:0xffffffffef95946d)
我可能不明白线性化方法是如何工作的,但它看起来很奇怪。
如果我继续,并且调用了 erase 方法,则会引发分段错误并且程序结束。如果我擦除的数据超过缓冲区容量,我可以理解,但事实并非如此。
有什么帮助吗?
你的memcpy是错误的。您正在将数据复制到 vector
对象本身的地址中,而不是将其复制到向量指向的位置。确保在调用此函数之前调用 vector::reserve
以避免不必要的内存取消分配和分配。
我会将函数重写为:
#include <iterator>
void CircularBuffer::extract(const unsigned int n,
vector<complex<float>>& destination)
{
// Wait until the buffer is not empty
std::unique_lock<mutex> l(lock);
notEmpty.wait(l, [this, n](){
return (int)(circularBuffer.size() - n) >= 0;
});
auto cb_ptr = circularBuffer.linearize();
assert (cb_ptr);
std::copy(cb_ptr, cb_ptr + n, std::back_inserter(destination));
circularBuffer.erase(circularBuffer.begin(), circularBuffer.begin() + n);
// Not full any more
notFull.notify_one();
}
我已经在我的 boost::circular_buffer
上实现了一个提取方法,它只是将 n
个元素复制到一个 destination
向量,然后从循环缓冲区中删除这 n 个元素(所以它更新内部指针,标记可以再次写入的位置):
void CircularBuffer::extract(const unsigned int n, vector<complex<float>> *destination){
// Wait until the buffer is not empty
std::unique_lock<mutex> l(lock);
notEmpty.wait(l, [this, n](){
return (int)(circularBuffer.size() - n) >= 0;
});
// We must copy n elements from a linearized version of the buffer
memcpy(destination, circularBuffer.linearize(), n);
// Remove extracted elements from circular buffer
circularBuffer.erase(circularBuffer.begin(), circularBuffer.begin() + n); //SIGSEGV
// Not full any more
notFull.notify_one();
}
当调用 erase
方法时,出现分段错误。
我使用以下尺码:
n = 9000
circularBuffer.size() = 9000 (at the moment when extract method is called)
circularBUffer.capacity() = 90000
但是,一旦 memcpy
行被执行,我猜是因为 linearize
调用,一切都乱七八糟,调试器显示:
circularBuffer.size() = 3238197033 (Hex: Hex:0xc102f729)
circularBUffer.capacity() = 18446744073434141805 (Hex:0xffffffffef95946d)
我可能不明白线性化方法是如何工作的,但它看起来很奇怪。
如果我继续,并且调用了 erase 方法,则会引发分段错误并且程序结束。如果我擦除的数据超过缓冲区容量,我可以理解,但事实并非如此。
有什么帮助吗?
你的memcpy是错误的。您正在将数据复制到 vector
对象本身的地址中,而不是将其复制到向量指向的位置。确保在调用此函数之前调用 vector::reserve
以避免不必要的内存取消分配和分配。
我会将函数重写为:
#include <iterator>
void CircularBuffer::extract(const unsigned int n,
vector<complex<float>>& destination)
{
// Wait until the buffer is not empty
std::unique_lock<mutex> l(lock);
notEmpty.wait(l, [this, n](){
return (int)(circularBuffer.size() - n) >= 0;
});
auto cb_ptr = circularBuffer.linearize();
assert (cb_ptr);
std::copy(cb_ptr, cb_ptr + n, std::back_inserter(destination));
circularBuffer.erase(circularBuffer.begin(), circularBuffer.begin() + n);
// Not full any more
notFull.notify_one();
}