[英]What happens, when changing ptr which is pointing to allocated memory using operator new to some other memory?
[英]What happens when Memory is allocated using a function?
当您通过函数返回新分配的变量时,是否会复制并传递一个副本,并自动删除原始副本?
我假设没有内存泄漏
#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?
}
输出是预期的。
当您返回新分配的变量时
具有动态存储的对象不是变量。
函数中有一个变量。 名为x
。 变量x
的类型为int*
即它是指向整数的指针。
复制并通过副本,原始副本会自动删除吗?
x
是一个自动变量,因此当它超出范围时会被自动销毁。 确实将变量作为返回值复制到调用表达式中-尽管,如果编译器执行命名返回值优化,则有可能删除该副本。 如果类型很大,或者复制速度很慢(指针不是),这将很有用。
具有动态存储(其类型在程序中为int
)的对象不会自动销毁。 必须使用delete
表达式将它们释放。
只要这样分配内存,就将其保留在“堆”上。 这是操作系统分配给程序的内存区域。 通过使用C ++中的分配函数,例如: new()
或malloc()
(还有其他分配函数),该堆的连续块得以保留,其地址(指针)返回到调用代码。
因此,在您的函数中:
int *allocater()
{
int *x = new int(1);
return x;
}
保留单个整数大小的内存(可能为4-8字节),并返回该内存的地址。 该地址只是一个数字,当将该数字解释为内存中的某个位置时,它称为指针-但它仍然只是一个数字。
因此,当函数返回时,内存仍然分配在堆上。 如果您的程序忘记了该数字,则该内存将“泄漏”-您的程序无法使用delete()
, delete[]()
或free()
对其进行delete()
分配,因为您没有该数字来告知解除分配功能在哪里免费。
在您的代码中,因为您存储了allocater()
的返回值,所以可以使用delete
取消分配该块。 因此,您的代码可以正常工作,并且可以正确地取消分配内存。
除非您释放它,否则什么都不会发生。 是的,这是有效的代码,没有泄漏。
在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
。
C ++没有垃圾收集器。 创建本地对象时,将在堆栈上分配内存,并且当它们超出范围时,编译器会自动调用析构函数(取决于对象是否不平凡),并在返回后释放内存。
但是,有时您需要动态分配内存。 在这种情况下,我们可以使用new
和delete
显式分配和删除内存。 但是,从C ++ 11开始,引入了智能指针,它们只是原始指针的包装。 这有助于管理对象的寿命。
原始指针的问题在于,程序员在不再有用时必须明确销毁该对象。
但是,这将由智能指针自动进行处理。
因此,在您的代码中, x
是一个局部变量,函数返回后立即返回。 x
被破坏,但它指向的内存没有被破坏。
非常感谢您非常有益的回复和反馈,确实有助于澄清问题,使用指针感觉就像是传递包裹的游戏!
因此只要分配的内存有指向它的指针-可以删除它而不会泄漏,无论是从函数返回还是在主函数中返回
非常感谢
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.