0

I have created a template class that implement a circular buffer. The buffer is formed of items that have a value of type T.

I want to define the operator[ ] to write and read an element of the buffer. Even when I try to read an element already inizialized the result is: Segmentation fault: 11

This is the code for 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;
    }
  }

An example of how I use operator[ ] in main.cpp:

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;

The error occurs when I try to write a new item in the buffer.

What could be a way to define the operator[ ] that works?

  • 1
    please post a [mcve]. In the code you show you never allocate memory for `buffer`, that is a possible reason for a segfault – 463035818_is_not_an_ai Sep 08 '20 at 10:50
  • Also please include how you use these operators, and run through a debugger to find out the exact line in your code where the crash happens. – Some programmer dude Sep 08 '20 at 10:51
  • I added more code, I hope it's enough to understand my project –  Sep 08 '20 at 11:32
  • The class you show looks less like a circular buffer and more like a generic expandable list-wrapper, which allows indexing to access nodes (similar to `ArrayList` in Java). to simplify things, use an actual array (possibly dynamically allocated). Or better yet a `std::vector` or `std::deque` for the actual "buffer", making it a *container adaptor* similar to `std::stack` or `std::queue`. – Some programmer dude Sep 08 '20 at 11:45

1 Answers1

1

I'm guessing somewhat, because you haven't provided enough context (it's difficult to see if a small part of a class is correct without seeing the rest of the class). But it seems that _buffer is a linked list. The next pointer in the item struct gives it away

typedef struct item {
    T value;
    item *next;
};

But your operator[] code assumes that _buffer is an array,

item *curr = _buffer + index;

Using + on a pointer assumes that the pointer is pointing at a contiguous block of memory but because you have a linked list that's not the case for you.

Instead you need to write a loop, that loops through your linked list until you find the correct item. Something like this

item *curr = _buffer;
while (index > 0) {
    curr = curr->next;
    --index;
}
return curr->value;
john
  • 85,011
  • 4
  • 57
  • 81
  • Thanks for the help, this method works when I want to read an item but not when I want to write, I'm trying to solve the problem of creating a new item before accessing it. –  Sep 08 '20 at 11:35
  • @user14237977 You need to use the same thing for existing nodes. And if you want to add a new element then you need to append it to the list (possibly appending *multiple* nodes). – Some programmer dude Sep 08 '20 at 11:36
  • How could it be a suitable append method? I tried but it works only to add the first element. –  Sep 08 '20 at 12:33
  • @user14237977 This is a different problem to the one here. You should make a new question and make sure to include all relevant code. – john Sep 08 '20 at 13:05
  • @user14237977 Also the new code above seems confused. You need to decide whether you are trying to use a linked list data structure or a dynamic array data structure. For instance capacity is not relevant to a linked list, but is to a dynamic array, and a next pointer is used in a linked list but not in a dynamic array. You need to get this straight first, its hard to write code when you are not sure what you are trying to do. – john Sep 08 '20 at 13:10
  • @john I'm trying to implement a linked list data structure but I need the capacity for other parts of the program, in this part is not useful –  Sep 08 '20 at 13:17