首页 > 解决方案 > C++如何定义操作符[]来读写循环缓冲区的一项

问题描述

我创建了一个实现循环缓冲区的模板类。缓冲区由具有类型 T 的值的项目组成。

我想定义 operator[ ] 来写入和读取缓冲区的元素。即使我尝试读取已经初始化的元素,结果也是:分段错误:11

这是 operator[ ] 的代码:

// 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;

当我尝试在缓冲区中写入新项目时发生错误。

有什么方法可以定义有效的 operator[]?

标签: c++segmentation-faultoperator-overloadingcircular-buffertemplate-classes

解决方案


我有点猜测,因为您没有提供足够的上下文(如果没有看到课程的其余部分,很难判断课程的一小部分是否正确)。但它似乎_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;

推荐阅读