ROOT Version: 6.16.00
Platform: Ubuntu 20.04 LTS
Compiler: gcc 9.3.0
when I tried to extract a sub-string from a string, I got some strange and inconsistent result, I don’t know why. Can someone help me, thank you.
root  string input("asym_usl.mean")
(std::string &) "asym_usl.mean"
root  int idx = input.find('.')
root  const char *a = input.substr(0, idx).c_str()
(const char *) "\x1e"
root  a
(const char *) "\xb0\x11\xe3" "E\x07V"
root  a
(const char *) "\x80\x85\xe9" "E\x07V"
root  a
(const char *) "\x10\xd4\xe9" "E\x07V"
root  a
(const char *) "\x90\xf9\xe9" "E\x07V"
root  a
(const char *) "\xc0\xc6\xe8" "E\x07V"
The problem is C++ related, in
const char *a = input.substr(0, idx).c_str() you are taking the value of a temporary. The value of the
c_str() is undefined on the next line.
You could do instead
string a = input.substr(0, idx)
Thank you for your answer, one further question is if I write those lines in a script and then run the script with root, I can get the correct answer. What causes the difference?
Now that you mention it, the result of
c_str() should actually remain valid until you destroy or modify the string (my “temporary” explanation was wrong, I think). Which would explain why it works in the script but not in the prompt. So apparently there is something more ongoing, cling related. @vvassilev can you explain the result?
The value printing actually captures the value, and indeed: at the time it’s printed the value is gone. I’d be happy to discuss whether / how that can be improved! @jalopezg @vvassilev I’ll contact you next week to see whether we can come up with a solution. Thanks for bringing this up, @weibin !
But until then, the workaround is to assign the temporary
substr() result to a
Thanks for bringing up this! Indeed,
input.substr(0, idx) creates a
std::string, copying characters from the original buffer. However, the constructed object is an r-value, i.e. the underlying buffer that you get via
.c_str() is not valid after destruction. This memory might get overwritten at any time.
I don’t know if we can workaround this in the interpreter, though. Perhaps, we can discuss it, @Axel, @vvassilev.
I think you were right? (EDIT: as Javi says, )
substr returns a new
std::string, which goes out of scope right after the statement is executed, leaving
a pointing to invalid memory.
I would not expect a different behavior from this, actually. cling prints the contents of
a, and that’s correctly garbage
@weibin when you run this code as a script it just might happen that the memory pointed by
a is not overwritten with different contents (it could be, it just happens not to be) – the use-after-delete is there but by chance it does not have visible effects.
I misread, there’s indeed nothing for us to fix.
const char * a = func_returning_a_std_string();
is undefined behavior; this has nothing to do with cling. Sorry I didn’t see the variable assignment before.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.