<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/73683>73683</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[libc++] basic_string move assignment can leak memory
</td>
</tr>
<tr>
<th>Labels</th>
<td>
libc++
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
daltenty
</td>
</tr>
</table>
<pre>
The following test program exhibits memory leaks when built with libc++ versions <= 6.0 and run against newer libc++ shared/dylibs:
```
$ cat test.cc
#include <string>
std::string* p;
void SetNoArena(::std::string&& value)
{
*p = std::move(value);
}
int main()
{
p = new ::std::string("Hello World!");
const char value1[128] = "A long enough string for heap allocation";
while(true){
SetNoArena( ::std::string(value1) );
}
delete p;
return 0;
}
$clang++ -nostdinc++ -isystem ~/libcxx-6.x/usr/local/include/c++/v1/ -nostdlib++ -L ~/libcxx-6.x/usr/local/lib/ -lc++ -lc++abi test.c
$export LD_LIBRARY_PATH=${HOME}/libcxx-17.x/usr/local/lib/:/usr/lib:/lib
$ ./a.out &
[1] 581514
$ ps -o pid,args,pmem
PID COMMAND %MEM
581514 ./a.out 0.7
...
$ ps -o pid,args,pmem
PID COMMAND %MEM
581514 ./a.out 0.8
...
$ ps -o pid,args,pmem
PID COMMAND %MEM
581514 ./a.out 0.9
```
Previous versions of libc++ before 7.0 used clear and shrink_to_fit in the move constructor to release the existing allocation as part of the move:
```
clear();
shrink_to_fit();
```
https://github.com/llvm/llvm-project/blob/d359f2096850c68b708bc25a7baca4282945949f/libcxx/include/string#L2106
In the same versions, shrink_to_fit() is implemented as an inline call to reduce().
Unfortunately, the C++ standard changed the semantics of reduce() in https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0966r1.html to never deallocate, which libc++ now implements (https://github.com/llvm/llvm-project/commit/4d64d7dd641d385439a354db1f98cbb0ab7167f9).
The deallocation was non-binding according to the standard, but unfortunately the string header implementation prior to LLVM 6.0 depends on that behaviour being present in the shared/dylib.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVk2P47gR_TX0pWBBor4PPtjtEWaA7t3BZpMgpwZFli3uUqRAUnb3Jb89oCR_DbqzmERouCmRrFf16lWRzDl51Igbku9Ivl-x0XfGbgRTHrV_X7VGvG9-7xAORilzlvoIHp2HwZqjZT3gWydb6R302Bv7DgrZnw7OHWpoR6k8nKXvQMmWE7ojdAcntE4a7YCkTyTdQxHFwLQAO2pgRya186DxjPZ-k-uYRUFoI96VbB1JtyTek_jyW8TL3_xKM-DMT35GnF8-plJzNQoMwM5bqY8k_XJvxnkRDKfbZZZuYSDp7n7JyUgBf0P_i9la1IzQ6rLjh60FoQWcmBqR0HqxUC6mYHkI3Q4QKLju7s0JCa2u-67g5f7eC6k99EzqAP-p9dm0xjN84mJFKP2KShn4p7FKEJoQSh9QH-xxEzLDO2bnuBKS7xJakXw_ARFKt6CMPgJqMx47mGHgYCx0yAZgShnOvDQ6wHyMce6kCgR4O8d_jemB8k8DWvyiNdyHcaX7QiIIVOjxLrmXJRb9aDXEHxBPM65YQJn0uNbGeSH1RZ9r6d6dxx7-TWgTdPv2ti6iN0Kb0dnwyXCmCG0WCRLaLDsJbU4Joc1iUcn2YvH5r2xNaxtYq6sTlxFr5SL-q_P4Nhjr4Xn_-vxt99v2t3-9ft_-_pWke0IzUu6-_vryJcR6BUzKTxED6dcZ2c6vYXAtvojQhkVm9BAKYf6c75IglbxK8iS7LR0crA0MUhD6xOzREfo09Njf0vL92x6efn152f4SNJa_fHlZ5mZLd1gfPnFUzuujKPofUT96_rsncVT9v6B_BVB_3Pmm3-8WT9KM7tZqzeG-mbZ4MBahjGIYHQrgCpmderDrrNR_vnrzepAepAbfIYSmNFe_Hbk3FrwBiwqZw2ke36TzodRvFQ7MwcCsD8AXE7ee_ejz1FuCB0s3u9bkgzM_TP5go_N-cLMQCW2O0ndjG3HTB2Gq0-XferDmD-Se0KZVJkhZpHl9oHFdVHnMi6ot46rlNGdlyzjLaEXrLK-z-nCti4cSvvSd9JkmcXGfgW8zc471eE0CoU8fhQTSgewHhT1qjyIwxzRIraRG4EypmW4xcpw3RPdAf9cHY_2omUf1HhAC7NPl0PRMC2ZFaNr6iGL2CXumveSTKO7thnQ_8ng-nyMzoF47LyJjj4Q2f3geupXj4aRozsdwZjTCcEdoM7ABbRjQOKnCe1wXhU2izvdTEBpPaEHgIhMM7p47yR9uB9qcb3Q4ILT66dxy0_eB3SYTRSZKIYosEWmVZ2nN0jwTbXKoK962MWvLpCgP9Y-khtvO1c2g5jNzoI1et1KLSeicGzuNvJlJXZgOIbWjh_E-LcuK6TTskAm0twhn-4OVc1k9P__jZboQCRxQCwcmCIl5aLFjoaYttBjsDBYd6muJPl6PopXYpKJOa7bCTVLGSVIXaVmsuk19yFPOWBHHouVtnPG2LQ6s4nXSZoxWdCU3NKZpktAqqVKaFxGWbYxJktE0i8syrkkWY8-kigLpQRQr6dyImzItqnSlWIvKTVdJSm9ZDQd-vl_ZzZSpdjw6ksVKOu9uZrz0CjdA8t3dvnwPLXOSvy70Ta1ovrEG9oAzPV04l8vnarRq89N6mQIIup1i-E8AAAD__6vyQ9I">