Reputation: 11831
Valgrind is giving me an invalid read error:
==37561== Invalid read of size 1
==37561== at 0x7E81: strlen (vg_replace_strmem.c:427)
for the following code within a class (which I think may be related to a trailing \0
, but I'm not sure).
std::queue<std::string> errorLog; ///< FIFO used to store errors
const char *Monitor::popErrorFromErrorLog() {
if (!errorLog.empty()) {
std::string str = errorLog.front();
errorLog.pop();
return str.c_str();
} else {
return nullptr;
}
}
void Monitor::reportError(std::string s) {
std::ostringstream err;
err << "Error reported: " << s << std::endl;
errorLog.push(err.str());
}
Any ideas what's wrong here please?
Upvotes: 0
Views: 1642
Reputation: 180630
std::string str = errorLog.front();
creates a local std::string
. When you use return str.c_str();
you are returning a pointer to the c-string that std::string
wraps. Once the return happens the string is destroyed and now you have returned a pointer to memory that has gone out of scope.
I would just return a std::string
so you do not have to worry about that. If you cannot do that then you will have to allocate storage dynamically(new{}) and then you will have to remember to clean it up(delete[]
) when you are done.
Upvotes: 1
Reputation: 5477
You are returning a c_str
-pointer to a std::string
that no longer exists: you pop it off the stack and copy its contents to a local variable, then you return the c_str
pointer of that local variable, which gets destroyed as the function returns.
As for the solution, why not just return std::string
rather than resorting to C strings?
Upvotes: 3