C++如何定义操作符[]来读写循环缓冲区的一项
Posted
技术标签:
【中文标题】C++如何定义操作符[]来读写循环缓冲区的一项【英文标题】:C++ how to define the operator [] to write and read an item of the circular buffer 【发布时间】:2020-12-26 17:54:10 【问题描述】:我创建了一个实现循环缓冲区的模板类。缓冲区由具有 T 类型值的项组成。
我想定义 operator[ ] 来写入和读取缓冲区的元素。即使我尝试读取已经初始化的元素,结果也是:Segmentation fault: 11
这是运算符[]的代码:
// read
const T& operator[](size_type index) const
assert(index < _size);
item *curr = _buffer + index;
return curr->value;
// read and write
T &operator[](size_type index)
assert(index < _capacity);
item *curr = _buffer + index;
if (index < _size)
return curr->value;
else
_size++;
return curr->value;
我如何在 main.cpp 中使用 operator[ ] 的示例:
cbuffer<int> b(4);
std::cout << "b: " << b << std::endl;
std::cout << "capacity: " << b.capacity() << std::endl;
assert(b.capacity() == 4);
std::cout << "size: " << b.size() <<
std::endl;
assert(b.size() == 0);
b[0] = 1;
b[1] = 3;
当我尝试在缓冲区中写入新项目时发生错误。
有什么方法可以定义有效的操作符[]?
【问题讨论】:
请发帖minimal reproducible example。在您展示的代码中,您从未为buffer
分配内存,这可能是段错误的原因
另外请包括您如何使用这些运算符,并通过调试器运行以找出发生崩溃的代码中的确切行。
我添加了更多代码,希望足以理解我的项目
你展示的类看起来不像一个循环缓冲区,而更像一个通用的可扩展列表包装器,它允许索引访问节点(类似于 Java 中的ArrayList
)。为了简化事情,使用一个实际的数组(可能是动态分配的)。或者更好的是std::vector
或std::deque
用于实际的“缓冲区”,使其成为类似于std::stack
或std::queue
的容器适配器。
【参考方案1】:
我有点猜测,因为您没有提供足够的上下文(如果不查看课程的其余部分,很难判断课程的一小部分是否正确)。但似乎_buffer
是一个链表。 item 结构中的next
指针泄露了它
typedef struct item
T value;
item *next;
;
但是您的operator[]
代码假定_buffer
是一个数组,
item *curr = _buffer + index;
在指针上使用+
会假定指针指向一个连续的内存块,但因为您有一个链表,但您的情况并非如此。
您需要编写一个循环,循环遍历您的链表,直到找到正确的项目。像这样的
item *curr = _buffer;
while (index > 0)
curr = curr->next;
--index;
return curr->value;
【讨论】:
感谢您的帮助,此方法在我想读取一个项目时有效,但在我想写入时无效,我正在尝试解决在访问之前创建一个新项目的问题。跨度> @user14237977 您需要对现有节点使用相同的东西。如果要添加新元素,则需要将其附加到列表中(可能附加 多个 节点)。 它怎么可能是一个合适的附加方法?我试过了,但它只适用于添加第一个元素。 @user14237977 这与这里的问题不同。您应该提出一个新问题并确保包含所有相关代码。 @user14237977 上面的新代码似乎也很混乱。您需要决定是尝试使用链表数据结构还是动态数组数据结构。例如容量与链表无关,但与动态数组有关,并且在链表中使用下一个指针但在动态数组中不使用。您需要先弄清楚这一点,当您不确定自己要做什么时,很难编写代码。以上是关于C++如何定义操作符[]来读写循环缓冲区的一项的主要内容,如果未能解决你的问题,请参考以下文章