Memory buffer implementation

Hi,

maybe my code is ugly (and suggestions are welcome)..
I've implemented a simple buffer class that store data in a vector.

A part of this class is this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
template<typename T>
struct TBuffer
{
  typedef typename std::vector<T>::size_type buff_size_type;

  std::vector<T>  data;
  buff_size_type  write_pos;
  buff_size_type  read_pos;

  TBuffer() : write_pos(0), read_pos(0) {};
};


template<typename T>
class Buffer
{
 private:
  TBuffer<T> buffer_;
  
 public:  
  EAudioLibRetVal Allocate(size_type num_of_items)
  { 
    try
    {        
      if (buffer_.data.capacity() < num_of_items)
        buffer_.data.reserve(num_of_items);
      buffer_.read_pos = 0;
      buffer_.write_pos = 0;
      return RV_NO_ERROR;
    }
    catch (std::bad_alloc e)
    {
      std::cerr << e.what() << endl;
      return RV_ERR_MEMORY_ERROR;
    }
  }

  size_type Write(const T* pData, size_type items)
  {
    try {
      std::copy(pData, pData + items, buffer_.data.begin() + buffer_.write_pos);
      buffer_.write_pos += (items * sizeof(T));
      return items;
    } catch (std::bad_alloc e)
    { 
      std::cerr << e.what() << endl; 
      return 0; 
    }
  }
  
};


in the write method I wanna copy a block of data pointed by pData into the vector and I've thought that std::copy was the best choice.
Running the code with this values:

buffer_.write_pos = 0
buffer_.data.capacity() = 1000
buffer_.data.size() = 0
items = 320

I get an assetion in <vector> at _SCL_SECURE_VALIDATE_RANGE:

("_Myptr + _Off <= ((_Myvec*)(this->_Gemycont()))->_Mylast && _Myptr + _Off >= ((_Myvec*)(this->_Getmycont()))->_Myfirst",0)

1
2
3
4
5
6
7
8
9
_Myt& operator+=(difference_type _Off)
{	// increment by integer
_SCL_SECURE_VALIDATE(this->_Has_container());
_SCL_SECURE_VALIDATE_RANGE(
  _Myptr + _Off <= ((_Myvec *)(this->_Getmycont()))->_Mylast &&
  _Myptr + _Off >= ((_Myvec *)(this->_Getmycont()))->_Myfirst);
_Myptr += _Off;
return (*this);
}


Seems that I go out of bound or something else..any idea?

Tnx in advance,
Daniele.
You should resize the vector in Allocate or use an inserter in the copy in Write. since you know how much space you need and you know you're going to use it all, you may as well do the former.
Thanks for the reply.

I used reserve because I've thought that it was a more convenient approach and the vector will be resized automatically in the std::copy.

So, instead of only reserve space, is better to resize the vector in Buffer::Allocate?
In this case, how should appears an inserter?

Tnx again,
Daniele.
reserve and resize do two different things.

reserve allocates enough memory to hold the specified number of elements, but does not change the number of elements actually in the vector. resize changes the number of elements actually in the vector to match the value specified. This may require reallocating a larger buffer.

So to do what you want to do, you will need to call resize() instead of reserve().

Yes, I know the difference, but I thought that I should reserve some data and leave the size to increase step by step like in the example here http://www.cplusplus.com/reference/stl/vector/reserve/

Maybe I can't use this approach with std::copy?
If you're going to do a copy into a zero size vector, you have to use an inserter.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <vector>
#include <iterator>
#include <algorithm>

int main()
{
    std::vector<int> w(10);
    for (size_t i = 0; i != w.size(); ++i)
        w[i] = int(i*i);

    std::vector<int> v;
    std::copy(
            w.begin(),
            w.end(),
            std::inserter<std::vector<int>, std::vector<int>::iterator>(v, v.begin()));

    return 0;
}
If write_pos is always guaranteed to be at the end, then you can just use std::back_inserter.

std::copy( pData, pData + items, std::back_inserter( buffer_.data ) );

Otherwise, it is a little more complicated:

buffer_.data.resize( buffer_.write_pos );
std::copy( pData, pData + items, std::back_inserter( buffer_.data ) );
Thanks to all for the explanations!
Daniele.
Topic archived. No new replies allowed.