繁体   English   中英

使用函数分配内存时会发生什么?

[英]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_ptrshared_ptr等。因此,如果使用它们:

int* allocater()
{
    auto x = std::make_unique<int>(5);
    return x.get();  // getting raw ptr
}

它是无效的,因为delete时,被称为x被破坏,当您退出这种情况allocater

C ++没有垃圾收集器。 创建本地对象时,将在堆栈上分配内存,并且当它们超出范围时,编译器会自动调用析构函数(取决于对象是否不平凡),并在返回后释放内存。

但是,有时您需要动态分配内存。 在这种情况下,我们可以使用newdelete显式分配和删除内存。 但是,从C ++ 11开始,引入了智能指针,它们只是原始指针的包装。 这有助于管理对象的寿命。

原始指针的问题在于,程序员在不再有用时必须明确销毁该对象。

但是,这将由智能指针自动进行处理。

因此,在您的代码中, x是一个局部变量,函数返回后立即返回。 x被破坏,但它指向的内存没有被破坏。

非常感谢您非常有益的回复和反馈,确实有助于澄清问题,使用指针感觉就像是传递包裹的游戏!

因此只要分配的内存有指向它的指针-可以删除它而不会泄漏,无论是从函数返回还是在主函数中返回

非常感谢

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM