[英]When exactly does the destruction of a temporary object happen in a function call?
This code compiles and executes.此代码编译并执行。 I know that we have undefined behaviour in the first case.
我知道在第一种情况下我们有未定义的行为。 But what happens exactly in the second case?
但是在第二种情况下到底发生了什么?
#include <string>
#include <iostream>
#include <cstdio>
std::string foo() {
return "HELLO";
}
void bar(const char *p) {
std::printf("%s\n", p);
}
int main() {
// FIRST CASE:
// I know this is bad, because after the assignment
// the variable returned by foo() is destroyed and we
// have a bad reference.
const std::string &s = foo();
bar(s.c_str());
// SECOND CASE:
// But what about that ? I don't know exactly if the
// object is alive after the call to c_str()
bar(foo().c_str());
return 0;
}
GCC output is in both cases "HELLO" but I think that's because it's not cleaning the raw memory. GCC 输出在两种情况下都是“HELLO”,但我认为这是因为它没有清理原始内存。
In the second case when exactly is the temporary object destroyed?在第二种情况下,临时对象究竟何时被销毁?
Actually, both of these cases are okay.其实这两种情况都可以。
In the first case, binding the temporary to a const
reference extends its lifetime to that of s
.在第一种情况下,将临时对象绑定到
const
引用会将其生命周期扩展到s
生命周期。 So it won't be destroyed until main
exits.所以它不会被销毁,直到
main
出口。
In the second case, the temporary is destroyed after the end of the full-expression containing it.在第二种情况下,临时对象在包含它的完整表达式结束后被销毁。 In this case, it is the function call.
在这种情况下,它是函数调用。 If you stored that C string anywhere which outlived
bar
and then tried to access it, then you're due a date with undefined behaviour.如果您将该 C 字符串存储在比
bar
寿命更长的任何位置,然后尝试访问它,那么您的到期日期将是未定义的行为。
Both of those cases are well-defined.这两种情况都是明确定义的。 To see a problematic case, store the result of
c_str()
until after the std::string
is destructed:要查看有问题的情况,请存储
c_str()
的结果,直到std::string
被破坏:
#include <string>
#include <cstdio>
std::string foo() {
return "HELLO";
}
void bar(const char *p) {
std::printf("%s\n", p);
}
int main() {
{
// FIRST CASE:
// This is okay, because the reference is const, so the object is alive
// until s goes out of scope.
const std::string &s = foo();
bar(s.c_str());
}
{
// VARIANT FIRST CASE:
// This is bad; the pointer is dangling
const char *s = foo().c_str();
bar(s);
}
{
// SECOND CASE:
// Is the object still alive after the call to c_str()? Yes, it's alive
// until after bar() has returned.
bar(foo().c_str());
}
return 0;
}
When I run this under Valgrind, it gives errors only for the variant case (with const char *s
):当我在 Valgrind 下运行它时,它仅针对变体情况(使用
const char *s
)给出错误:
==9981== Invalid read of size 1
==9981== at 0x4C2E0E2: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9981== by 0x543EC7B: puts (ioputs.c:36)
==9981== by 0x400937: bar(char const*) (37946437.cpp:9)
==9981== by 0x4009AA: main (37946437.cpp:25)
==9981== Address 0x5aabcf8 is 24 bytes inside a block of size 30 free'd
==9981== at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9981== by 0x4F058FD: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22)
==9981== by 0x40099E: main (37946437.cpp:24)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.