diff --git a/stl/inc/syncstream b/stl/inc/syncstream index 1437ca8ac1..3e41b9925c 100644 --- a/stl/inc/syncstream +++ b/stl/inc/syncstream @@ -218,11 +218,14 @@ protected: } const _Size_type _New_capacity = _Calculate_growth(_Buf_size, _Buf_size + 1, _Max_allocation); - const _Elem* const _Old_ptr = streambuf_type::pbase(); + _Elem* const _Old_ptr = streambuf_type::pbase(); const _Size_type _Old_data_size = _Get_data_size(); _Elem* const _New_ptr = _Unfancy(_Al.allocate(_New_capacity)); _Traits::copy(_New_ptr, _Old_ptr, _Old_data_size); + if (0 < _Buf_size) { + _Al.deallocate(_Refancy<_Pointer>(_Old_ptr), _Buf_size); + } streambuf_type::setp(_New_ptr, _New_ptr + _Old_data_size, _New_ptr + _New_capacity); streambuf_type::sputc(_Traits::to_char_type(_Current_elem)); diff --git a/tests/std/test.lst b/tests/std/test.lst index 61e5d7af1f..2d067dfbe7 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -204,6 +204,7 @@ tests\GH_002558_format_presetPadding tests\GH_002581_common_reference_workaround tests\GH_002655_alternate_name_broke_linker tests\GH_002711_Zc_alignedNew- +tests\GH_002760_syncstream_memory_leak tests\LWG2597_complex_branch_cut tests\LWG3018_shared_ptr_function tests\LWG3121_constrained_tuple_forwarding_ctor diff --git a/tests/std/tests/GH_002760_syncstream_memory_leak/env.lst b/tests/std/tests/GH_002760_syncstream_memory_leak/env.lst new file mode 100644 index 0000000000..351a8293d9 --- /dev/null +++ b/tests/std/tests/GH_002760_syncstream_memory_leak/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_20_matrix.lst diff --git a/tests/std/tests/GH_002760_syncstream_memory_leak/test.cpp b/tests/std/tests/GH_002760_syncstream_memory_leak/test.cpp new file mode 100644 index 0000000000..bb8200aace --- /dev/null +++ b/tests/std/tests/GH_002760_syncstream_memory_leak/test.cpp @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// REQUIRES: debug_CRT + +#include +#include +#include +#include +using namespace std; + +// GH-2760, : std::osyncstream memory leak +int main() { + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); + [[maybe_unused]] _CrtMemState start; + [[maybe_unused]] _CrtMemState end; + [[maybe_unused]] _CrtMemState diff; + _CrtMemCheckpoint(&start); + { + stringstream s; + osyncstream bout(s); + bout << "Hello, this line is long, which previously leaked memory" << '\n'; + } + _CrtMemCheckpoint(&end); + assert(_CrtMemDifference(&diff, &start, &end) == 0); +}