diff --git a/include/locale b/include/locale index 78f85d8d..7920f5ed 100644 --- a/include/locale +++ b/include/locale @@ -2970,6 +2970,8 @@ __double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e) size_t __cur_cap = static_cast(__e-__b.get()) * sizeof(_Tp); size_t __new_cap = __cur_cap < numeric_limits::max() / 2 ? 2 * __cur_cap : numeric_limits::max(); + if (__new_cap == 0) + __new_cap = sizeof(_Tp); size_t __n_off = static_cast(__n - __b.get()); _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap); if (__t == 0) diff --git a/src/ios.cpp b/src/ios.cpp index 06426c7b..d879beb3 100644 --- a/src/ios.cpp +++ b/src/ios.cpp @@ -154,6 +154,16 @@ atomic ios_base::__xindex_ = ATOMIC_VAR_INIT(0); int ios_base::__xindex_ = 0; #endif +template +static size_t __ios_new_cap(size_t __req_size, size_t __current_cap) +{ // Precondition: __req_size > __current_cap + const size_t mx = std::numeric_limits::max() / sizeof(_Tp); + if (__req_size < mx/2) + return _VSTD::max(2 * __current_cap, __req_size); + else + return mx; +} + int ios_base::xalloc() { @@ -166,14 +176,8 @@ ios_base::iword(int index) size_t req_size = static_cast(index)+1; if (req_size > __iarray_cap_) { - size_t newcap; - const size_t mx = std::numeric_limits::max(); - if (req_size < mx/2) - newcap = _VSTD::max(2 * __iarray_cap_, req_size); - else - newcap = mx; - size_t newsize = newcap * sizeof(long); - long* iarray = static_cast(realloc(__iarray_, newsize)); + size_t newcap = __ios_new_cap(req_size, __iarray_cap_); + long* iarray = static_cast(realloc(__iarray_, newcap * sizeof(long))); if (iarray == 0) { setstate(badbit); @@ -182,8 +186,9 @@ ios_base::iword(int index) return error; } __iarray_ = iarray; - for (long* p = __iarray_ + __iarray_size_; __iarray_cap_ < newcap; ++__iarray_cap_, ++p) + for (long* p = __iarray_ + __iarray_size_; p < __iarray_ + newcap; ++p) *p = 0; + __iarray_cap_ = newcap; } __iarray_size_ = max(__iarray_size_, req_size); return __iarray_[index]; @@ -195,14 +200,8 @@ ios_base::pword(int index) size_t req_size = static_cast(index)+1; if (req_size > __parray_cap_) { - size_t newcap; - const size_t mx = std::numeric_limits::max(); - if (req_size < mx/2) - newcap = _VSTD::max(2 * __parray_cap_, req_size); - else - newcap = mx; - size_t newsize = newcap * sizeof(void*); - void** parray = static_cast(realloc(__parray_, newsize)); + size_t newcap = __ios_new_cap(req_size, __iarray_cap_); + void** parray = static_cast(realloc(__parray_, newcap * sizeof(void *))); if (parray == 0) { setstate(badbit); @@ -211,8 +210,9 @@ ios_base::pword(int index) return error; } __parray_ = parray; - for (void** p = __parray_ + __parray_size_; __parray_cap_ < newcap; ++__parray_cap_, ++p) + for (void** p = __parray_ + __parray_size_; p < __parray_ + newcap; ++p) *p = 0; + __parray_cap_ = newcap; } __parray_size_ = max(__parray_size_, req_size); return __parray_[index]; @@ -226,22 +226,16 @@ ios_base::register_callback(event_callback fn, int index) size_t req_size = __event_size_ + 1; if (req_size > __event_cap_) { - size_t newcap; - const size_t mx = std::numeric_limits::max(); - if (req_size < mx/2) - newcap = _VSTD::max(2 * __event_cap_, req_size); - else - newcap = mx; - size_t newesize = newcap * sizeof(event_callback); - event_callback* fns = static_cast(realloc(__fn_, newesize)); + size_t newcap = __ios_new_cap(req_size, __event_cap_); + event_callback* fns = static_cast(realloc(__fn_, newcap * sizeof(event_callback))); if (fns == 0) setstate(badbit); __fn_ = fns; - size_t newisize = newcap * sizeof(int); - int* indxs = static_cast(realloc(__index_, newisize)); + int* indxs = static_cast(realloc(__index_, newcap * sizeof(int))); if (indxs == 0) setstate(badbit); __index_ = indxs; + __event_cap_ = newcap; } __fn_[__event_size_] = fn; __index_[__event_size_] = index;