当我有一个非dinamically分配的对象时,我按值返回:
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
}
在哪些情况下会发生内存泄漏?
答案 0 :(得分:7)
没有内存泄漏,但案例3甚至没有模糊的有效。
get()
函数返回可能已优化的字符串副本,因为std::string
是一个类而不是指针或其他任何东西。从用户的角度来看,它与从函数返回int
大致相同:创建并返回副本,并在函数范围之外保持有效,以便允许赋值或使用。如果没有这种行为,通常就不可能返回值。
它非常类似地应用于POD和类(尽管类需要复制构造函数等)。您应该能够为几乎所有std
课程执行此操作,但制作副本的成本会有所不同(例如,返回std::vector<BigClass>(1000)
是一个坏主意)。根据设置,您的编译器可能能够通过RVO优化副本。
案例1 使用:副本分配给str
,没有内存泄漏,没问题。很简单。
案例2 会丢弃副本,但仍然没有问题。
案例3 将尝试获取临时返回值的地址,该值将被编译器快速销毁(由于未使用)并使ptr
成为挂起指针。在临时消失后使用ptr
将导致未定义的行为,可能是访问冲突。临时将被销毁的地点和时间将取决于您的编译器,设置和其他您不能依赖的东西。
正确的表单是 1 (虽然 2 也有效,但不是很有用)。
答案 1 :(得分:2)
由于您没有在堆上动态分配任何内存(使用new
或malloc
和朋友),您的示例都不会泄漏。
答案 2 :(得分:1)
对于std类和简单类型,“应该”永远不会泄漏。对于海关类,您可以创建一个正确分配和释放其内部资源的类。