Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

memset on vector<int>

As per Mark Ransoms answer on using memset, i am using memset on a vector<int> to assign values to all the elements.

memset(&match_begin[0], 0xff , sizeof(match_begin[0]) * match_begin.size());

It does have a significant performance improvement over std::fill and it works fine(g++ 4.3.2, 64bit linux). Is this code safe , as in , would std::vector implementations always guarantee that memory allocation for the data will be contiguous? Is it possible that in a future(or different) implementation of the stl library that this might change and break my code later?

like image 826
woodstok Avatar asked Apr 08 '13 09:04

woodstok


People also ask

Can I use memset on vector?

Explanation: The memset() in C++ can be used for vectors as mentioned above.

Can we use memset in C++?

Memset() is a C++ function. It copies a single character for a specified number of times to an object. It is useful for filling a number of bytes with a given value starting from a specific memory location. It is defined in <cstring> header file.

How do you use the memset function?

The memset() function takes three arguments: dest , ch and count . The character represented by ch is first converted to unsigned char and then copies it into the first count characters of the object pointed to by dest . The behaviour of the function is undefined if: The object is not trivially copyable.

Does memset need to be freed?

No overhead of memory freed is there for the programmer in the memset function as it does not allocate any memory which needs to be freed explicitly.


3 Answers

would std::vector implementations always guarantee that memory allocation for the data will be contiguous

Yes. 23.3.6.1/1. In C++03 standard there are equal strings at 23.2.4/1

The elements of a vector are stored contiguously, meaning that if v is a vector where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size()

Is it possible that in a future(or different) implementation of the stl library that this might change and break my code later?

No. Vector should be contiguous always.

However, in gcc 4.6.3 there is only one optimization of fill, using memset. This optimization is for char types

  // Specialization: for char types we can use memset.
  template<typename _Tp>
    inline typename
    __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, void>::__type
    __fill_a(_Tp* __first, _Tp* __last, const _Tp& __c)
    {
      const _Tp __tmp = __c;
      __builtin_memset(__first, static_cast<unsigned char>(__tmp),
               __last - __first);
    }
like image 158
ForEveR Avatar answered Oct 09 '22 14:10

ForEveR


This should be safe from a memory perspective.

Just bear in mind that if the content of your vector is not a plain data type, you shouldn't be doing this sort of thing.

like image 32
Mats Petersson Avatar answered Oct 09 '22 14:10

Mats Petersson


memset fails with vector of bool type, just try below example, though as other mentioned it work for other plain data type.I shared it just to make it explicit its not true for all plain data types.

#include <vector>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
    vector<bool>vec;
    vec.push_back(0);
    vec.push_back(1);
    memset(&vec[0], 0, sizeof(vec[0]) * vec.size());
    return 0;
}
like image 26
Saqlain Avatar answered Oct 09 '22 15:10

Saqlain