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::vectorstd::deque 用于实际的“缓冲区”,使其成为类似于std::stackstd::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++如何定义操作符[]来读写循环缓冲区的一项的主要内容,如果未能解决你的问题,请参考以下文章

C++学习50 对字符串流的读写

如何在 Windows 10 上使用 C++ 将连续的原始音频数据记录到循环缓冲区中?

C++ 缓冲文件读取

python自动化学习笔记3-集合函数模块

帧缓冲设备应用开发

用c语言或c++编写编程实现生产者消费者或读写者的同步问题