Look at this example. If v = v[std::slice{0, 4, 1}] isn't UB itself(I'm not too sure), then it is dangerously implemented currently.
#include<valarray>
int main() {
std::valarray v{1, 2, 3, 4, 5};
v = v[std::slice{0, 4, 1}];
}
In the current implementation, this means v will firstly do _Tidy_deallocate, which deallocates _Myptr; then do _Grow, reading data from _Myptr.
template <class _Ty>
valarray<_Ty>& valarray<_Ty>::operator=(const slice_array<_Ty>& _Slicearr) {
_Tidy_deallocate();
_Grow(_Slicearr.size(), &_Slicearr._Data(_Slicearr.start()), _Slicearr.stride());
return *this;
}
Take the above code for example, a fixed version would be:
template <class _Ty>
valarray<_Ty>& valarray<_Ty>::operator=(const slice_array<_Ty>& _Slicearr) {
valarray<_Ty> _Val(_Slicearr);
swap(_Val);
return *this;
}
All the following four functions have the same problem.
|
valarray& operator=(const slice_array<_Ty>& _Slicearr); // defined below
|
|
|
|
valarray& operator=(const gslice_array<_Ty>& _Gslicearr); // defined below
|
|
|
|
valarray& operator=(const mask_array<_Ty>& _Maskarr); // defined below
|
|
|
|
valarray& operator=(const indirect_array<_Ty>& _Indarr); // defined below
|
Look at this example. If
v = v[std::slice{0, 4, 1}]isn't UB itself(I'm not too sure), then it is dangerously implemented currently.In the current implementation, this means
vwill firstly do_Tidy_deallocate, which deallocates_Myptr; then do_Grow, reading data from_Myptr.Take the above code for example, a fixed version would be:
All the following four functions have the same problem.
STL/stl/inc/valarray
Lines 187 to 193 in a621095