当我有一个非动态分配的对象并且我按值返回它时:
string get()
{
string str("hello");
return str;
}
有机会得到内存泄漏?我举几个例子:
int main(int argc, char** argv)
{
string str=get(); // case 1
get(); // case 2
string* ptr=&get(); // case 3
}
什么情况下会发生内存泄漏?
最佳答案
没有内存泄漏,但情况 3 甚至不是模糊有效的。
get()
函数返回字符串的拷贝,可能经过优化,因为 std::string
是一个类而不是指针或其他任何东西。从用户的角度来看,它的工作原理与返回 int
大致相同。来自函数:创建并返回一个拷贝,并在函数范围之外保持有效,以便允许分配或使用。没有这种行为,一般来说返回值是不可能的。
它非常相似地适用于 POD 和类(尽管类需要复制构造函数等)。您应该能够对几乎所有 std
执行此操作类,尽管制作拷贝的成本会有所不同(例如,返回 std::vector<BigClass>(1000)
是个坏主意)。根据设置,您的编译器可能能够通过 RVO 优化复制。
案例 1 使用:拷贝分配给 str
,没有内存泄漏,没问题。很简单。
案例 2 丢弃了拷贝,但仍然没有问题。
情况 3 将尝试获取临时返回值的地址,该地址将很快被编译器销毁(由于未使用)并生成 ptr
一个悬挂的指针。任何使用 ptr
临时消失后会导致未定义的行为,可能是访问冲突。何时何地销毁临时文件将取决于您的编译器、设置和其他您不能依赖的东西。
正确的形式是1(虽然2也是有效的,只是不是很有用)。
关于c++ - 按值返回堆栈中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9432650/