Re: valgrind 's "invalid read" error
This looks suspect:
Code:
const char* array = stream.str().c_str();
You get a pointer from a temporary string object. This pointer is then invalidated once this temporary string object is destroyed. Is there any reason why you cannot write instead:
Code:
std::string array(stream.str())
?
valgrind 's "invalid read" error
Hi All,
Given the following piece of code in D.cpp :
Code:
//set string myString
//set boolean myBoolean2 and myBoolean1
bool marked = false;
size_t len = stream.str().length();
const char* array = stream.str().c_str();
if( len != 0 && !myBoolean1 )
{
/* This is line 791 ---->>>>>* / if(len >= 4 && myString == "test" && !array[len - 1] && !array[len - 2] && !array[len - 3] && !array[len - 4] && !myBoolean2)
{
marked = true;
}
myFunction();
}
Valgrind generates the invalid read error below:
Code:
==10564== Invalid read of size 1
==10564== at 0x69CACFF: C::D::SaveServerReply() (D.cpp:791)
==10564== by 0x69CC6C9: C::D::ExtractNextServerReply(char const*, unsigned long long) (D.cpp:370)
==10564== by 0x69A5BA4: A::B::OnApplication() (B.cpp:207)
==10564== by 0x409F91: main (my_daemon.cc:890)
==10564== Address 0x99e0f07 is 3,095 bytes inside a block of size 3,097 free'd
==10564== at 0x4C24A7A: operator delete(void*) (vg_replace_malloc.c:346)
==10564== by 0x69CADA1: C::D::SaveServerReply() (basic_string.h:231)
==10564== by 0x69CC6C9: C::D::ExtractNextServerReply(char const*, unsigned long long) (D.cpp:370)
==10564== by 0x69A5BA4: A::B::OnApplication() (B.cpp:207)
==10564== by 0x409F91: main (my_daemon.cc:890)
Apparently, that piece of code tries to read some part of memory which is already free'd.
However, FOR THE SAME DATA, this piece of code sometimes crashes and sometimes not on different runs of the program.
What is the safe way of rewriting this code ?
Thanks.
Re: valgrind 's "invalid read" error
This looks suspect:
Code:
const char* array = stream.str().c_str();
You get a pointer from a temporary string object. This pointer is then invalidated once this temporary string object is destroyed. Is there any reason why you cannot write instead:
Code:
std::string array(stream.str())
?
Re: valgrind 's "invalid read" error
Quote:
Originally Posted by aryan1
When does an invalidation of a pointer take place ?
The pointer returned by c_str() is invalidated when a non-const member function of the corresponding string object is called, and in this case that would be the destructor.
Quote:
Originally Posted by aryan1
I think that it depends on the layout of the memory at a certain time.
Hence, even for the same data, that is why the piece of code above sometimes crashes and sometimes not on different runs.
Do you agree ?
No, the invalidation does not depend on the layout of the memory. The effects of the undefined behaviour due to the dereferencing of an invalid pointer, on the other hand, may depend on the memory involved.
Re: valgrind 's "invalid read" error
Quote:
Originally Posted by
laserlight
This looks suspect:
Code:
const char* array = stream.str().c_str();
You get a pointer from a temporary string object. This pointer is then invalidated once this temporary string object is destroyed. Is there any reason why you cannot write instead:
Code:
std::string array(stream.str())
?
No, there is no reason - It's just bad programming.
When does an invalidation of a pointer take place ?
I think that it depends on the layout of the memory at a certain time.
Hence, even for the same data, that is why the piece of code above sometimes crashes and sometimes not on different runs.
Do you agree ?
Re: valgrind 's "invalid read" error
The test line could be called with any len != 0.
So array[ len -4] is invalid when len==1.
order of evaluation isn't guaranteed, see here.
Re: valgrind 's "invalid read" error
Quote:
Originally Posted by aryan1
When does an invalidation of a pointer take place ?
The pointer returned by c_str() is invalidated when a non-const member function of the corresponding string object is called, and in this case that would be the destructor.
Quote:
Originally Posted by aryan1
I think that it depends on the layout of the memory at a certain time.
Hence, even for the same data, that is why the piece of code above sometimes crashes and sometimes not on different runs.
Do you agree ?
No, the invalidation does not depend on the layout of the memory. The effects of the undefined behaviour due to the dereferencing of an invalid pointer, on the other hand, may depend on the memory involved.
Re: valgrind 's "invalid read" error
Thank you.
That's what I thought; double checking.
Re: valgrind 's "invalid read" error
This is the exact question I've wanted to ask for a while, but never got around to doing it.
If I were to write:
Code:
size_t size = stream.str().size(); (1)
string str(stream.str().c_str()); (2)
In (1), when size() is called, is the temporary string still existent?
If yes:
In (2), when str's constructor is called, are the temporary string and associated char array still valid?
I short, in the above expressions, when does the compiler determine the temporaries have finished their lifetime? At the end of the expression?
Re: valgrind 's "invalid read" error
Quote:
Originally Posted by monarch_dodra
In (1), when size() is called, is the temporary string still existent?
Yes.
Quote:
Originally Posted by monarch_dodra
In (2), when str's constructor is called, are the temporary string and associated char array still valid?
Yes.
Quote:
Originally Posted by monarch_dodra
I short, in the above expressions, when does the compiler determine the temporaries have finished their lifetime? At the end of the expression?
Quote:
Originally Posted by C++03 Section 12.2 Paragraph 3
Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception.
Re: valgrind 's "invalid read" error
Thank you.
That's what I thought; double checking.