通过函数返回新分配的变量时,是否会复制并传递一个副本,并且会自动删除原始副本?
我假设没有内存泄漏
#include <iostream>
using namespace std;
int* allocater()
{
int* x = new int(1);
return x;
// what happens to the memory allocated to x ?
}
int main()
{
int* a = allocater();
int* b = allocater();
cout<<*a<<" "<<*b;
delete a;
delete b;
// all memory allocated has been deleted?
}
输出符合预期。
答案 0 :(得分:5)
返回新分配的变量时
具有动态存储的对象不是变量。
该函数中有一个变量。它的名称为x
。变量x
的类型为int*
,即它是指向整数的指针。
是否制作并通过了副本,并且原件会自动删除?
x
是一个自动变量,因此当它超出范围时会被自动销毁。确实将变量作为返回值复制到调用表达式中-尽管,如果编译器执行命名返回值优化,则有可能删除该副本。如果类型较大或复制速度较慢(指针没有复制),则很有用。
具有动态存储(程序中类型为int
)的对象不会自动销毁。必须使用delete
表达式释放它们。
答案 1 :(得分:1)
每当这样分配内存时,它就会保留在“堆”上。这是操作系统分配给程序的内存区域。通过使用C ++中的分配函数,例如:new()
或malloc()
(还有其他),该堆的连续块被保留,其地址(指针)返回到堆。调用代码。
在您的函数中:
int *allocater()
{
int *x = new int(1);
return x;
}
保留单个整数大小的内存(可能为4-8字节),并返回该内存的地址。该地址只是一个数字,当将该数字解释为内存中的某个位置时,它称为指针-但它仍然只是一个数字。
因此,当函数返回时,内存仍然分配在堆上。如果您的程序忘记了该数字,则该内存将“泄漏”-您的程序无法使用delete()
,delete[]()
或free()
对其进行取消分配,因为您没有该数字来告知取消分配功能可在何处释放。
在您的代码中,因为您存储了allocater()
的返回值,所以可以使用delete
来取消分配该块。因此,您的代码可以正常工作,并且可以正确地取消分配内存。
答案 2 :(得分:0)
在释放它之前什么都不会发生。是的,这是有效的代码,没有泄漏。
在C ++ 11(或更早的auto_ptr
-s中)引入了RAII指针:unique_ptr
,shared_ptr
等。因此,如果使用它们:
int* allocater()
{
auto x = std::make_unique<int>(5);
return x.get(); // getting raw ptr
}
它变得无效,因为delete
被销毁时x
被调用,而退出allocater
时会发生这种情况。
答案 3 :(得分:0)
C ++没有垃圾收集器。创建本地对象时,将在堆栈上分配内存,并且当它们超出范围时,编译器会自动调用析构函数(取决于对象是否平凡),并在返回后释放内存。
但是,有时您需要动态分配内存。在这种情况下,我们可以使用new
和delete
显式分配和删除内存。但是,从C ++ 11开始,引入了智能指针,它们只是原始指针的包装。这有助于管理对象的寿命。
原始指针的问题在于,当对象不再有用时,程序员必须明确销毁该对象。
但是,智能指针会自动照顾这一点。
因此,在您的代码中,x
是一个局部变量,函数将立即返回。 x
被销毁,但它指向的内存未被销毁。
答案 4 :(得分:-1)
非常感谢您的翔实回答和反馈,确实有助于澄清问题, 使用指针就像传递包裹的游戏!
,只要分配的内存有指向它的指针-它可以是 删除而没有泄漏,无论是从函数返回还是在主函数中返回
非常感谢