http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60371

            Bug ID: 60371
           Summary: std::vector::emplace_back
           Product: gcc
           Version: 4.8.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dilyan.palauzov at aegee dot org

I use gcc 4.8.3 20140220 (prerelease), with libc 2.17 on a x86_64 bit system.

Compiling:
#include <vector>
#include <string.h>
#include <stdlib.h>

struct z {
  char* var;
  z (const char* str) { var = strdup (str);  }
  ~z () { free (var); }
};

std::vector<z> y;

int main () {
  y.emplace_back ("a");
  y.emplace_back ("b");
}

with
gcc -O0 -ggdb3 -std=c++11 vector_emplace_back.cpp -o vector_emplace_back
-lstdc++
I get the attached binary file.

Running valgrind revision 13842 on the resulting file with

valgrind --tool=memcheck --track-origins=yes ./vector_emplace_back

results the output

== Memcheck, a memory error detector
== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
== Command: ./vector_emplace_back
==
== Invalid free() / delete / delete[] / realloc()
==    at 0x4C2B10C: free (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==    by 0x400B1C: z::~z() (vector_emplace_back.cpp:8)
==    by 0x401495: void std::_Destroy<z>(z*) (stl_construct.h:93)
==    by 0x401397: void std::_Destroy_aux<false>::__destroy<z*>(z*, z*)
(stl_construct.h:103)
==    by 0x4012C5: void std::_Destroy<z*>(z*, z*) (stl_construct.h:126)
==    by 0x401103: void std::_Destroy<z*, z>(z*, z*, std::allocator<z>&)
(stl_construct.h:151)
==    by 0x4015DC: std::vector<z, std::allocator<z> >::~vector()
(stl_vector.h:415)
==    by 0x53871E0: __run_exit_handlers (in /lib64/libc-2.17.so)
==    by 0x5387264: exit (in /lib64/libc-2.17.so)
==    by 0x5370A2B: (below main) (in /lib64/libc-2.17.so)
==  Address 0x59fc090 is 0 bytes inside a block of size 2 free'd
==    at 0x4C2B10C: free (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==    by 0x400B1C: z::~z() (vector_emplace_back.cpp:8)
==    by 0x401495: void std::_Destroy<z>(z*) (stl_construct.h:93)
==    by 0x401397: void std::_Destroy_aux<false>::__destroy<z*>(z*, z*)
(stl_construct.h:103)
==    by 0x4012C5: void std::_Destroy<z*>(z*, z*) (stl_construct.h:126)
==    by 0x401103: void std::_Destroy<z*, z>(z*, z*, std::allocator<z>&)
(stl_construct.h:151)
==    by 0x400D70: void std::vector<z, std::allocator<z>
>::_M_emplace_back_aux<char const (&) [2]>(char const (&) [2]) (vector.tcc:428)
==    by 0x400BC6: void std::vector<z, std::allocator<z> >::emplace_back<char
const (&) [2]>(char const (&) [2]) (vector.tcc:101)
==    by 0x400A6E: main (vector_emplace_back.cpp:15)
==
==
== HEAP SUMMARY:
==     in use at exit: 0 bytes in 0 blocks
==   total heap usage: 4 allocs, 5 frees, 28 bytes allocated
==
== All heap blocks were freed -- no leaks are possible
==
== For counts of detected and suppressed errors, rerun with: -v
== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 1 from 1)

There shall not be "double free()".

Inserting y.clear(); between the two y.emplace_back() does not lead to any
warnings from valgrind for the whole resulting programme.

std::list does not have this problem, as expected.

Reply via email to