![](/img/trans.png)
[英]What happen when a lvalue assigned to a rvalue reference? No destruction of the temporary object?
[英]When exactly does the destruction of a temporary object happen in a function call?
此代碼編譯並執行。 我知道在第一種情況下我們有未定義的行為。 但是在第二種情況下到底發生了什么?
#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 輸出在兩種情況下都是“HELLO”,但我認為這是因為它沒有清理原始內存。
在第二種情況下,臨時對象究竟何時被銷毀?
其實這兩種情況都可以。
在第一種情況下,將臨時對象綁定到const
引用會將其生命周期擴展到s
生命周期。 所以它不會被銷毀,直到main
出口。
在第二種情況下,臨時對象在包含它的完整表達式結束后被銷毀。 在這種情況下,它是函數調用。 如果您將該 C 字符串存儲在比bar
壽命更長的任何位置,然后嘗試訪問它,那么您的到期日期將是未定義的行為。
這兩種情況都是明確定義的。 要查看有問題的情況,請存儲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;
}
當我在 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.