Thread: invalid read

  1. #1
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694

    invalid read

    I have run my program so many times, but it does not crash and has correct results. valgrind however says something for invalid read.

    What I do in the code it crashes is this:
    I have a map, where every idnex leads to a set.
    The sat contains pairs.
    It looks something like this:
    ..
    991 => 434, 1 529, 1 687, 1 699, 1 713, 1 0, 0 1, ..
    992 => 76, 1 192, 1 244, 1 383, 1 404, 1 528, 1 616, ..
    ..

    and I want to erase some pairs, based on some conditions.

    I have located the piece of code this happens:
    Code:
        counter = 0;
        // delete from DS the best candidates
        for(size_t i = 0 ; i < v.size() && counter != v.size() ; ++i) {
        	std::cout << "edw0 " << i << std::endl;
          for(std::map< unsigned int, std::set< std::pair<unsigned int, int>,
              classcomp > >::iterator it1 =
              p_similarTo_pCount.begin() ; it1 != p_similarTo_pCount.end() ; ++it1) {
            if(it1->first == v[i].p_) {
            	std::cout << "edw2" << std::endl;
              for(std::set< std::pair<unsigned int, int>, classcomp >::iterator it2
                  = it1->second.begin() ; it2 != it1->second.end() ; ++it2) {
                if(it2->first == v[i].p_c_.first && it2->second == v[i].p_c_.second) {
                	std::cout << "edw4" << std::endl;
                std::cout << it1->first << " " <<
                      it2->first << " "<<it2->second << std::endl;
                  Print2(p_similarTo_pCount, it1->first);
                  std::cout << "edw5" << std::endl;
                  it1->second.erase(*it2);
                  std::cout << "edw6" << std::endl;
                  counter++;
                  std::cout << "edw7" << std::endl;
                }
              }
            }
          }
        }
    Also this is the Print2(), if someone wants it.
    Code:
    void Print2(  std::map< unsigned int, std::set<
                 std::pair<unsigned int, int>, classcomp > >& p,
                 unsigned int which
    ) {
      std::map< unsigned int, std::set<
                   std::pair<unsigned int, int>, classcomp > >::const_iterator it;
      std::set<std::pair<unsigned int, int>, classcomp >::const_iterator it1;
      for(it = p.begin() ; it != p.end() ; ++it) {
      	if(which == it->first){
        	std::cout << it->first << " => ";
        	for(it1 = it->second.begin() ; it1 != it->second.end() ; ++it1) {
          	std::cout << it1->first << ", " << it1->second << " ";
        	}
        	std::cout << "\n";
        }
      }
      std::cout << "\n";
    }
    and then here is what valgrind says:
    Code:
    ==8945== Memcheck, a memory error detector
    ==8945== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
    ==8945== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
    ==8945== Command: ./s datasets/outputDir-1k/outputDir-1k/ datasets/1k-sample-queries.txt
    ==8945== 
    edw0 0
    edw2
    edw4
    174 280 3
    174 => 280, 3 21, 1 194, 1 211, 1 251, 1 320, 1 434, 1 631, 1 699, 1 785, 1 812, 1 980, 1 0, 0 1, 0 2, 0 10, 0 11, 0 22, 0 38, 0 63, 0 64, 0 65, 0 66, 0 67, 0 
    
    edw5
    edw6
    edw7
    ==8945== Invalid read of size 4
    ==8945==    at 0x40A2BE5: std::_Rb_tree_increment(std::_Rb_tree_node_base*) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
    ==8945==    by 0x805CB61: query_3::Query3::Execute(int, int, std::string) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x8049A99: main (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==  Address 0x449e3e4 is 12 bytes inside a block of size 24 free'd
    ==8945==    at 0x402ACFC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==8945==    by 0x8063332: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<unsigned int, int> > >::deallocate(std::_Rb_tree_node<std::pair<unsigned int, int> >*, unsigned int) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x8062C91: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::_M_put_node(std::_Rb_tree_node<std::pair<unsigned int, int> >*) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x806206B: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::_M_destroy_node(std::_Rb_tree_node<std::pair<unsigned int, int> >*) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x806113F: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::_M_erase_aux(std::_Rb_tree_const_iterator<std::pair<unsigned int, int> >) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x805F46D: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::erase(std::_Rb_tree_const_iterator<std::pair<unsigned int, int> >) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x80626ED: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::_M_erase_aux(std::_Rb_tree_const_iterator<std::pair<unsigned int, int> >, std::_Rb_tree_const_iterator<std::pair<unsigned int, int> >) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x8061332: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::erase(std::_Rb_tree_iterator<std::pair<unsigned int, int> >, std::_Rb_tree_iterator<std::pair<unsigned int, int> >) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x805F4B8: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::erase(std::pair<unsigned int, int> const&) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x805DF61: std::set<std::pair<unsigned int, int>, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::erase(std::pair<unsigned int, int> const&) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x805CB07: query_3::Query3::Execute(int, int, std::string) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x8049A99: main (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945== 
    ==8945== Invalid read of size 4
    ==8945==    at 0x40A2BFB: std::_Rb_tree_increment(std::_Rb_tree_node_base*) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
    ==8945==    by 0x805CB61: query_3::Query3::Execute(int, int, std::string) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x8049A99: main (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==  Address 0x449e3dc is 4 bytes inside a block of size 24 free'd
    ==8945==    at 0x402ACFC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==8945==    by 0x8063332: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<unsigned int, int> > >::deallocate(std::_Rb_tree_node<std::pair<unsigned int, int> >*, unsigned int) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x8062C91: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::_M_put_node(std::_Rb_tree_node<std::pair<unsigned int, int> >*) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x806206B: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::_M_destroy_node(std::_Rb_tree_node<std::pair<unsigned int, int> >*) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x806113F: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::_M_erase_aux(std::_Rb_tree_const_iterator<std::pair<unsigned int, int> >) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x805F46D: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::erase(std::_Rb_tree_const_iterator<std::pair<unsigned int, int> >) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x80626ED: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::_M_erase_aux(std::_Rb_tree_const_iterator<std::pair<unsigned int, int> >, std::_Rb_tree_const_iterator<std::pair<unsigned int, int> >) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x8061332: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::erase(std::_Rb_tree_iterator<std::pair<unsigned int, int> >, std::_Rb_tree_iterator<std::pair<unsigned int, int> >) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x805F4B8: std::_Rb_tree<std::pair<unsigned int, int>, std::pair<unsigned int, int>, std::_Identity<std::pair<unsigned int, int> >, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::erase(std::pair<unsigned int, int> const&) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x805DF61: std::set<std::pair<unsigned int, int>, query_3::classcomp, std::allocator<std::pair<unsigned int, int> > >::erase(std::pair<unsigned int, int> const&) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x805CB07: query_3::Query3::Execute(int, int, std::string) (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945==    by 0x8049A99: main (in /home/samaras/DIT/SIGMOD/code+answers/s)
    ==8945== 
    edw0 1
    edw2
    edw4
    280 812 3
    280 => 174, 3 812, 3 232, 2 361, 2 194, 1 251, 1 264, 1 320, 1 429, 1 434, 1 522, 1 629, 1 631, 1 655, 1 693, 1 706, 1 0, 0 1, 0 2, 0 10, 0 11, 0 21, 0 22, 0 38, 0 
    
    edw5
    edw6
    edw7
    edw0 2
    edw2
    edw4
    361 812 4
    361 => 812, 4 270, 2 280, 2 38, 1 232, 1 333, 1 350, 1 405, 1 583, 1 629, 1 633, 1 706, 1 721, 1 761, 1 782, 1 0, 0 1, 0 2, 0 10, 0 11, 0 21, 0 22, 0 63, 0 64, 0 
    
    edw5
    edw6
    edw7
    361|812 174|280 280|812 % common interest counts 4 3 3
    ==8945== 
    ==8945== HEAP SUMMARY:
    ==8945==     in use at exit: 0 bytes in 0 blocks
    ==8945==   total heap usage: 42,537 allocs, 42,537 frees, 1,404,865 bytes allocated
    ==8945== 
    ==8945== All heap blocks were freed -- no leaks are possible
    ==8945== 
    ==8945== For counts of detected and suppressed errors, rerun with: -v
    ==8945== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 0 from 0)

    If I use a "return;" immediately after the erase(), it won't crash. If I use a return after the piece of code I posted, it will crash.

    What's going on? :/

    I read that what valgrind actually says, is that acess something that is freed, but where?
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Remember that iterators are evil things. If you start messing with the containers, you may just end up invalidating the iterators you've saved.
    Well, for set specifically, only the iterator you delete will be invalidated. Nevertheless, I don't think you should be able to increment an invalid iterator (which happens after you delete the iterator from the set on the next iteration of the loop).
    Of course, I could be totally wrong, but without a test set of data and necessary structures to test it, I can't say much more.
    I also took the liberty of fixing the indentation of code style because your code was pretty horrible. Also removed the iterator types to make the code more readable:

    Code:
    closecounter = 0;
    // delete from DS the best candidates
    for (size_t i = 0; i < v.size() && counter != v.size(); ++i)
    {
        std::cout << "edw0 " << i << std::endl;
        for (auto map_it = p_similarTo_pCount.begin(); map_it != p_similarTo_pCount.end(); ++map_it)
        {
            if (map_it->first == v[i].p_)
            {
                std::cout << "edw2" << std::endl;
                for (auto set_it = map_it->second.begin(); set_it != map_it->second.end(); ++set_it)
                {
                    if (set_it->first == v[i].p_c_.first && set_it->second == v[i].p_c_.second)
                    {
                        std::cout << "edw4" << std::endl;
                        std::cout << map_it->first << " " <<
                            set_it->first << " " << set_it->second << std::endl;
                        Print2(p_similarTo_pCount, map_it->first);
                        std::cout << "edw5" << std::endl;
                        map_it->second.erase(*set_it);
                        std::cout << "edw6" << std::endl;
                        counter++;
                        std::cout << "edw7" << std::endl;
                    }
                }
            }
        }
    }
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Wow, that was it. First time I experienced that, tnx. Yeah, the identation was bad.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Invalid read error
    By Giorgos in forum C Programming
    Replies: 14
    Last Post: 05-03-2013, 01:38 PM
  2. Valgrind - Invalid read of size 1
    By Castelmagno in forum C Programming
    Replies: 7
    Last Post: 02-29-2012, 03:19 PM
  3. Valgrind Invalid Read/Write In C Program
    By Alex Richman in forum C Programming
    Replies: 2
    Last Post: 10-02-2011, 03:15 PM
  4. Invalid Read from Valgrind
    By jduro in forum C Programming
    Replies: 1
    Last Post: 10-05-2010, 11:28 AM
  5. read() returns invalid file descriptor ???
    By hoho in forum C Programming
    Replies: 4
    Last Post: 08-04-2006, 10:54 AM