jeudi 30 juin 2016

Bad allocation error when my_list.push_back()

I am trying to control de workflow of a program I am developing. To do so I have a map< unsigned int, list < unsigned int > > in which the first key will be the id and the second ( the list ) will be used to know if I end correctly all tasks. The only operations I use on this list are:

myMap[iD].size()
myMap[iD].push_back(foo) <- ( foo is an unsigned int )
for (std::list<unsigned int>::iterator it=myMap[iD].begin(); it != myMap[iD].end(); ++it){
myMap[iD].erase(it)
}

The length of my map can grow to 1452 elements and each element list size can be from the order of 1000 ~ 5000.

When I run the program sometimes I receive a segmentation fault and some times a bad allocation error. My guess is that this come from the push_back because:

  • If I don't push back any element the program works fine.
  • The storage for the new elements is allocated using the container's allocator, which may throw exceptions on failure (for the default allocator, bad_alloc is thrown if the allocation request does not succeed). http://ift.tt/299Khe9

This is the only part of the code where I use the map:

if (FOO != 0){
    if (PID != 0){

        if ( myMap.size() + 5 < myMap.size().max_size()){
            if (myMap.size()[PID].size() > 1000) myMap.size()[PID].pop_front();
            myMap.size()[PID].push_back(EVENTVALUE);
        }

    }
} else {
    if (PID != 0 and foo2 != 0 and myMap.size().find(PID) != myMap.size().end()) {
        for (std::list<unsigned int>::iterator it=myMap.size()[PID].begin(); it != myMap.size()[PID].end(); ++it){
            if (*it == foo2){
                cout << " erasing pid: " << PID <<  endl;
                myMap.size()[PID].erase(it);
                if ( myMap.size()[PID].size() == 0 ) myMap.size().erase(PID);
                break;
            }

        }
    }
}

I've also tried to use the tool Valgrind and this is the output:

==4092== Invalid read of size 8
==4092==    at 0x4F09EB8: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (in /usr/lib64/libstdc++.so.6.0.21)
==4092==    by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (new_allocator.h:120)
==4092==    by 0x40CCA9: _S_construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:254)
==4092==    by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:393)
==4092==    by 0x40CCA9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:905)
==4092==    by 0x4157AC: foo::foo(std::basic_ofstream<char, std::char_traits<char> >&) (foo.cc:1743)
==4092==    by 0x404F49: main (foo.cc:3159)
==4092==  Address 0x6157d08 is 0 bytes after a block of size 8 alloc'd
==4092==    at 0x4C29670: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==4092==    by 0x40DB77: allocate (new_allocator.h:104)
==4092==    by 0x40DB77: _M_allocate (stl_vector.h:168)
==4092==    by 0x40DB77: void std::vector<std::string, std::allocator<std::string> >::_M_emplace_back_aux<std::string>(std::string&&) (vector.tcc:404)
==4092==    by 0x408F3E: push_back (stl_vector.h:920)
==4092==    by 0x408F3E: split(std::string const&, char, int) (foo.cc:416)
==4092==    by 0x41577F: lustreLine::toPRV(std::basic_ofstream<char, std::char_traits<char> >&) (foo.cc:1741)
==4092==    by 0x404F49: main (foo.cc:3159)
==4092== 
==4092== Invalid read of size 4
==4092==    at 0x4F09EBB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (in /usr/lib64/libstdc++.so.6.0.21)
==4092==    by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (new_allocator.h:120)
==4092==    by 0x40CCA9: _S_construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:254)
==4092==    by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:393)
==4092==    by 0x40CCA9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:905)
==4092==    by 0x4157AC: foo::foo(std::basic_ofstream<char, std::char_traits<char> >&) (foo.cc:1743)
==4092==    by 0x404F49: main (foo.cc:3159)
==4092==  Address 0xfffffffffffffff8 is not stack'd, malloc'd or (recently) free'd
==4092== 
==4092== 
==4092== Process terminating with default action of signal 11 (SIGSEGV)
==4092==  Access not within mapped region at address 0xFFFFFFFFFFFFFFF8
==4092==    at 0x4F09EBB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (in /usr/lib64/libstdc++.so.6.0.21)
==4092==    by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (new_allocator.h:120)
==4092==    by 0x40CCA9: _S_construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:254)
==4092==    by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:393)
==4092==    by 0x40CCA9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:905)
==4092==    by 0x4157AC: foo::foo(std::basic_ofstream<char, std::char_traits<char> >&) (fpp.cc:1743)
==4092==    by 0x404F49: main (foo.cc:3159)
==4092==  If you believe this happened as a result of a stack
==4092==  overflow in your program's main thread (unlikely but
==4092==  possible), you can try to increase the size of the
==4092==  main thread stack using the --main-stacksize= flag.
==4092==  The main thread stack size used in this run was 8388608.

[...]

( If more output is need just ask )

I've had to change some variable names for privacy, hope this is not a problem.

Thanks for reading and have a nice day!

Aucun commentaire:

Enregistrer un commentaire