CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Jun 2009
    Posts
    118

    Question "invalid read" error

    Hi All,

    Following two functions, one of which is called by the other, causes an "invalid read" error to be generated by valgrind:

    Code:
    FILE* open_file(flow_state_t* flowState)
    {
      std::string filename(flow_filename(flowState->flow));
      ...
    }
    Code:
    const char* flow_filename(flow_t flow)
    {
      static std::stringstream streamFileName;
      streamFileName.str("");
    
      streamFileName << inet_ntoa(flow.src) << "." << flow.sport << "-";
      streamFileName << inet_ntoa(flow.dst) << "." << flow.dport;
    
      return streamFileName.str().c_str();
    }
    If I interpret the valgrind's output correctly, two functions above should be enough to identify the cause of the error.

    Here is the output of valgrind:

    Code:
    ==4683== Invalid read of size 1                                                                                                
    ==4683==    at 0x40276E8: strlen (mc_replace_strmem.c:242)                                                                                                                          
    ==4683==    by 0x40D788A: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.10)                                                                                                                                                                              
    ==4683==    by 0x805D03C: open_file(flow_state_struct*)
    ==4683==    by 0x804B4E9: createFlowState(char const*, flow_t, unsigned int, flow_state_struct*, int) (my_daemon.cc:912)                                                          
    ==4683==    by 0x804E277: main (my_daemon.cc:566)                                                                                                                                 
    ==4683==  Address 0x42ea7cc is 12 bytes inside a block of size 49 free'd                                                                                                            
    ==4683==    at 0x402599A: operator delete(void*) (vg_replace_malloc.c:342)                                                                                                          
    ==4683==    by 0x40D69FC: std::string::_Rep::_M_destroy(std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.10)                                                              
    ==4683==    by 0x40D83B0: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/libstdc++.so.6.0.10)                                 
    ==4683==    by 0x805CF9E: flow_filename(flow_t)
    ==4683==    by 0x805D026: open_file(flow_state_struct*)
    ==4683==    by 0x804B4E9: createFlowState(char const*, flow_t, unsigned int, flow_state_struct*, int) (my_daemon.cc:912)                                                          
    ==4683==    by 0x804E277: main (my_daemon.cc:566)
    Why does valgrind reckon that I should not read the return value of flow_filename(flowState->flow) into std::string filename in open_file() ? (These code snippets come from a third-party library)

    Thanks.

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: "invalid read" error

    stringstream::str() returns a temporary string object. Therefore that string is gone by the time the function returns, and thus the c_str() you're calling is invalid.

    I have never used Valgrind, but the output suggests that is what is happening (look at the delete on the string object).

    Why not remove all doubts and return a full-fledged string from the function, instead of const char*? If your user-code is using strings, then use strings all the way (that's the way I do things). The only time I resort to const char * is if I'm calling a function not written by me that needs a const char *. (and in that case, I call c_str()).

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Jun 2009
    Posts
    118

    Re: "invalid read" error

    Quote Originally Posted by Paul McKenzie View Post
    I have never used Valgrind, but the output suggests that is what is happening (look at the delete on the string object).
    Do you have any other better suggestions for debug tools in Linux other than Valgrind ?

    I recently began to use Valgrind since I saw that it is referred in many places.

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: "invalid read" error

    Quote Originally Posted by aryan1 View Post
    Do you have any other better suggestions for debug tools in Linux other than Valgrind ?
    I don't use Linux, that's why I stated that I have never used valgrind.

    A good code review without debugging anything, or using a good lint utility would have spotted the error before anything was run, so valgrind really isn't necessary in this case (the same code could have crashed on Windows using Visual C++, and there is no valgrind for Windows).

    Basically, here is a simple app that outlines what you're trying to do. The "whatever" class is a dummy for stringstream, and also has a str() function.
    Code:
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    struct whatever
    {
       public:
          std::string str() 
         { 
              std::string s;  // Here is my string
              s = "abc123";
              return s; 
         }
    };
    
    const char* foo()
    {
        static whatever w;
        return w.str().c_str();
    }  // string is temporary.  Now it's gone.
    
    int main()
    {
       cout << foo();
    }
    Run this with valgrind. This is basically what stringstream::str() is attempting to do. The str() function returns a string, no problem. The problem is that the return value is being destroyed once c_str() has executed, so the destruction of the return string happens even before the foo() function exits. So the solution is to return str() directly instead of trying to return c_str().

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; December 20th, 2009 at 01:19 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured