本文共 2965 字,大约阅读时间需要 9 分钟。
最近fix一个崩溃问题,崩溃关键信息如标题如示,具体的原因调用:assign(const value_type* __s, size_type __n)时第二个参数传了负数,负数赋值到无符号long时就是一个很大的正数了!
basic_string<_CharT, _Traits, _Allocator>&basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n){ _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr"); size_type __cap = capacity(); if (__cap >= __n) { value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); traits_type::move(__p, __s, __n); traits_type::assign(__p[__n], value_type()); __set_size(__n); __invalidate_iterators_past(__n); } else { size_type __sz = size(); __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); } return *this;}voidbasic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace (size_type __old_cap, size_type __delta_cap, size_type __old_sz, size_type __n_copy, size_type __n_del, size_type __n_add, const value_type* __p_new_stuff){ size_type __ms = max_size(); if (__delta_cap > __ms - __old_cap - 1) this->__throw_length_error(); //这里抛异常,导致崩溃 pointer __old_p = __get_pointer(); size_type __cap = __old_cap < __ms / 2 - __alignment ? __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); __invalidate_all_iterators(); if (__n_copy != 0) traits_type::copy(_VSTD::__to_raw_pointer(__p), _VSTD::__to_raw_pointer(__old_p), __n_copy); if (__n_add != 0) traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy, __p_new_stuff, __n_add); size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; if (__sec_cp_sz != 0) traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add, _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del, __sec_cp_sz); if (__old_cap+1 != __min_cap) __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); __set_long_pointer(__p); __set_long_cap(__cap+1); __old_sz = __n_copy + __n_add + __sec_cp_sz; __set_long_size(__old_sz); traits_type::assign(__p[__old_sz], value_type());}
具体的业务场可以抽像成出下示例代码
int main() { string test; char a[10] {'\0', 'c', 'c', 'b'}; unsigned long maxSize = -1; cout << "size = " << strlen(a) << endl; cout << "maxSize = " << maxSize << ", string.max_size = " << test.max_size() << endl; test.assign(a, strlen(a) - 1);}
如上代码的运行结果(macOS上)
/Users/dw_luogongwu/CLionProjects/untitled1/cmake-build-debug/untitled1size = 0maxSize = 18446744073709551615, string.max_size = 18446744073709551599libc++abi.dylib: terminating with uncaught exception of type std::length_error: basic_stringProcess finished with exit code 6
转载地址:http://vumbi.baihongyu.com/