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?
Explanation: The memset() in C++ can be used for vectors as mentioned above.
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.
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.
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.
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);
}
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.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With