<html>
<head>
<base href="http://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - libc++ std::ostrstream leaks memory."
href="http://llvm.org/bugs/show_bug.cgi?id=22021">22021</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>libc++ std::ostrstream leaks memory.
</td>
</tr>
<tr>
<th>Product</th>
<td>libc++
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>FreeBSD
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>All Bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>ruffianeo@googlemail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvmbugs@cs.uiuc.edu, mclow.lists@gmail.com
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>Running either of the two programs below shows, that std::ostrstream leaks
large amounts of memory, while std::ostringstream does not. While not shown
here, it possibly also overwrites memory.
The only difference between those 2 programs is the switch from strstream to
sstream and from std::ostrsream to std::ostringstream.
compiled with:
clang++ -std=c++11 -stdlib=libc++ buggy.cpp -o buggy
and
clang++ -std=c++11 -stdlib=libc++ not_buggy.cpp -o not_buggy
respectively.
Then run as:
valgrind ./buggy
and
valgrind ./not_buggy.
Buggy.cpp
// Uses strstream header and std::ostrstream
#include <iostream>
#include <strstream>
#include <fstream>
#include <stdint.h>
static std::string MessageComposer( uint32_t index )
{
std::ostrstream stm;
stm << "This is message #" << index << "." << std::endl;
return stm.str();
}
int main( int argc, char * argv[] )
{
for( uint32_t i = 0; i < 100; ++i )
{
std::cout << MessageComposer(i);
}
return 0;
}
not_buggy.cpp
// uses sstream and std::ostringstream.
#include <iostream>
#include <sstream>
#include <fstream>
#include <stdint.h>
static std::string MessageComposer( uint32_t index )
{
std::ostringstream stm;
stm << "This is message #" << index << "." << std::endl;
return stm.str();
}
int main( int argc, char * argv[] )
{
for( uint32_t i = 0; i < 100; ++i )
{
std::cout << MessageComposer(i);
}
return 0;
}
Valgrind summary for the buggy version:
==26471==
==26471== HEAP SUMMARY:
==26471== in use at exit: 413,696 bytes in 101 blocks
==26471== total heap usage: 101 allocs, 0 frees, 413,696 bytes allocated
==26471==
==26471== LEAK SUMMARY:
==26471== definitely lost: 409,600 bytes in 100 blocks
==26471== indirectly lost: 0 bytes in 0 blocks
==26471== possibly lost: 0 bytes in 0 blocks
==26471== still reachable: 4,096 bytes in 1 blocks
==26471== suppressed: 0 bytes in 0 blocks
==26471== Rerun with --leak-check=full to see details of leaked memory
==26471==
==26471== For counts of detected and suppressed errors, rerun with: -v
==26471== Use --track-origins=yes to see where uninitialised values come from
==26471== ERROR SUMMARY: 100 errors from 1 contexts (suppressed: 0 from 0)
Valgrind summary for the not_buggy version:
==26474==
==26474== HEAP SUMMARY:
==26474== in use at exit: 4,096 bytes in 1 blocks
==26474== total heap usage: 1 allocs, 0 frees, 4,096 bytes allocated
==26474==
==26474== LEAK SUMMARY:
==26474== definitely lost: 0 bytes in 0 blocks
==26474== indirectly lost: 0 bytes in 0 blocks
==26474== possibly lost: 0 bytes in 0 blocks
==26474== still reachable: 4,096 bytes in 1 blocks
==26474== suppressed: 0 bytes in 0 blocks
==26474== Rerun with --leak-check=full to see details of leaked memory
==26474==
==26474== For counts of detected and suppressed errors, rerun with: -v
==26474== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>