指针释放和堆内存,c ++

时间:2015-12-02 08:59:44

标签: c++ pointers memory memory-management heap

我有一个我调用的成员函数,从那里我得到一个指向类BankAccount的私有成员的指针,我不确定当我释放它们时指针会发生什么。我创建一个新的指针和堆内存地址,但然后将指针指定给其他东西。什么"删除"最终删除?

如果删除指针,我会读到

这是代码

void Employee::raise(){

    BankAccount* tempBank = new BankAccount(); //set pointer to new heap place

    double amt;

    tempBank = get_bank(); // set pointer to existing heap implicitly
    amt = tempBank->get_amount();
    amt = (amt + (amt/12));
    tempBank->set_amount(amt);


    delete tempBank; //does this delete new heap created or does it add a new block of
                     //memory to heap since it is trying to delete a pointer assigned 
                     //by memory address
    tempBank = NULL;
}

我意识到我可以只做下面的代码来避免这种情况,但现在我很好奇上面的情况会发生什么事情

BankAccount* tempBank = get_bank();

那么在原始情况下调用delete时会发生什么?

6 个答案:

答案 0 :(得分:1)

当您使用delete ptr;时,ptr指向的对象将被销毁,相应的内存将返回到内存管理系统。变量ptr及其任何副本都包含一个位模式,指的是现在无法访问的内存(系统可能仍然允许您实际访问此内存,它甚至可能仍包含原始数据,但这是未定义的行为,您不应该依赖在它上面。)

换句话说,内存释放不会影响指针,但它会影响指向的实体。在您的情况下,BankAccount,即*tempBank的结果被tempBank操作保持不变,指针delete保持不变。显然,将tempBank设置为NULL确实会更改此特定指针,但不会更改其他副本(如果有),从而给出错误的安全感:我不会将delete指针设置为NULL除非我出于某种原因将它们留在身边......

答案 1 :(得分:1)

指针基本上只是内存中第一个字节的地址,属于它们指向的数据结构。所以在你的情况下:

BankAccount* tempBank = new BankAccount(); // this creates a new object of type BankAccount
                                           // the pointer tempBank points to the first byte of that object in memory

tempBank = get_bank();  // now tempBank points to the first byte of whatever is returned from get_bank()
                        // that means that you no longer know the address of the object you created above (tempBank now points to something different)
                        // C++ has no garbage collection, so you just leaked that memory

delete tempBank; // you delete the object that was returned from get_bank
                 // so that memory is now marked as free and can be reused by whatever needs it

tempBank = NULL;  // this is good style, you should always do it, but it does nothing to any allocated memory

BTW:在现代C ++中,使用普通的new和删除并拥有原始指针被认为是坏的风格。你可能想考虑使用std :: shared_ptr或std :: unique_ptr(或者如果你还不能使用C ++ 11那么它们的提升等价物)

答案 2 :(得分:0)

我发现这些信息可能对您有用:

普通删除释放由ptr指向的内存块(如果不为null),释放先前通过调用operator new分配给它的存储空间,并使该指针位置无效。

您可以在原始网址中找到更多信息:http://www.cplusplus.com/reference/new/operator%20delete/

答案 3 :(得分:0)

delete tempBank;

当在指针上调用delete时,它会释放该变量[tempBank]指向的内存。

C ++中有两种删除概念:一种是运算符,声明为:: operator delete(void *),它基本上只释放内存,大多数程序员通常都不会想到。另一个是删除表达式,删除p;,其中p是T *。该表达式调用p指向的对象的析构函数(然后释放内存),这是C ++的一个关键语言特性,在C语言中没有模拟。

答案 4 :(得分:0)

首先,您要从堆中分配第一个exp

BankAccount* tempBank = new BankAccount();

并且通过

为tempBank指针指定另一个对象地址而丢失了它的地址
tempBank = get_bank();

实际上,当您delete tempBank;实际删除在函数get_bank()中分配的对象时。另外因为你丢失了用new BankAccount()分配的对象的地址,所以没有更多的方法可以删除它,因为你不知道这个对象的地址。

答案 5 :(得分:0)

在你的问题中,你确定get_bank()确实返回指向堆上分配的对象的指针(而不是堆栈上普通对象的地址)。你没有清楚地提到它,因此再次证实它是值得的。现在,回过头来问一下,如果get_bank()返回指向私有成员的指针,让我们说它不在堆上 - 在这种情况下,执行doing tempBank会导致未定义的行为,因为你只能调用delete在使用new创建的对象上。但是如果get_bank()返回指向堆上分配的对象的指针,那么它将释放该对象的内存,然后从任何其他成员函数访问该对象可能会成为一场噩梦!

您可以查看以下链接以获取更多相关信息,

Calling delete on variable allocated on the stack