在C ++中删除指针

时间:2012-11-04 22:02:31

标签: c++ pointers delete-operator

背景:我正试图围绕指针,我们几周前在学校看到它们,今天练习时我遇到了傻瓜?问题,对你来说可能非常简单,但我几乎没有任何编程经验。

我在SO中看到了很多关于删除指针的问题,但它们似乎都与删除一个类有关,而不是一个“简单”指针(或任何正确的术语),这里是代码I'我想跑:

#include <iostream>;

using namespace std;

int main() {
  int myVar,
      *myPointer;

  myVar = 8;
  myPointer = &myVar;

  cout << "delete-ing pointers " << endl;
  cout << "Memory address: " << myPointer << endl;

  // Seems I can't *just* delete it, as it triggers an error 
  delete myPointer;
  cout << "myPointer: " << myPointer << endl;
  // Error: a.out(14399) malloc: *** error for object 0x7fff61e537f4:
  // pointer being freed was not allocated
  // *** set a breakpoint in malloc_error_break to debug
  // Abort trap: 6

  // Using the new keyword befor deleting it works, but
  // does it really frees up the space? 
  myPointer = new int;
  delete myPointer;
  cout << "myPointer: " << myPointer << endl;
  // myPointer continues to store a memory address.

  // Using NULL before deleting it, seems to work. 
  myPointer = NULL;
  delete myPointer;
  cout << "myPointer: " << myPointer << endl;
  // myPointer returns 0.

}

所以我的问题是:

  1. 为什么第一个案例不起作用?似乎最直接的使用和删除指针?错误表示内存未分配,但'cout'返回了一个地址。
  2. 在第二个示例中,没有触发错误,但是对myPointer 的值仍然执行cout会返回内存地址吗?
  3. #3真的有效吗?似乎对我有用,指针不再存储地址,这是删除指针的正确方法吗?
  4. 很抱歉这个长期的问题,想尽可能清楚地说明这一点,同样重申,我的编程经验很少,所以如果有人能用外行的条款回答这个问题,我们将不胜感激!

6 个答案:

答案 0 :(得分:138)

1&amp; 2

myVar = 8; //not dynamically allocated. Can't call delete on it.
myPointer = new int; //dynamically allocated, can call delete on it.

第一个变量是在堆栈上分配的。您只能在使用new运算符动态分配的内存(在堆上)上调用delete。

第3

  myPointer = NULL;
  delete myPointer;

以上根本没有。你没有释放任何东西,因为指针指向NULL。


不应执行以下操作:

myPointer = new int;
myPointer = NULL; //leaked memory, no pointer to above int
delete myPointer; //no point at all

您将其指向NULL,留下泄漏的内存(您分配的新int)。 你应该释放你指向的记忆。无法再访问已分配的new int,因此内存泄漏。


正确方法:

myPointer = new int;
delete myPointer; //freed memory
myPointer = NULL; //pointed dangling ptr to NULL

更好的方法:

如果您使用的是C ++,不要使用原始指针。使用smart pointers代替它可以为您处理这些事情,而且开销很小。 C ++ 11附带several

答案 1 :(得分:17)

我相信你并没有完全理解指针是如何工作的 如果指针指向某个内存,则必须了解三种不同的内容:
- 指针(存储器)有“指向的东西”
- 这个记忆地址
- 并非所有指针都需要删除内存:您只需要删除动态分配的内存(使用new运算符)。

想象:

int *ptr = new int; 
// ptr has the address of the memory.
// at this point, the actual memory doesn't have anything.
*ptr = 8;
// you're assigning the integer 8 into that memory.
delete ptr;
// you are only deleting the memory.
// at this point the pointer still has the same memory address (as you could
//   notice from your 2nd test) but what inside that memory is gone!

当你做了

ptr = NULL;
// you didn't delete the memory
// you're only saying that this pointer is now pointing to "nowhere".
// the memory that was pointed by this pointer is now lost.

C ++允许您尝试delete一个指向null的指针,但实际上并没有做任何事情,只是没有给出任何错误。

答案 2 :(得分:11)

指针与普通变量类似,因为您不需要删除它们。它们在函数执行结束时和/或程序结束时从内存中删除。

然而,您可以使用指针来分配内存的“块”,例如:

int *some_integers = new int[20000]

这将为20000个整数分配内存空间。很有用,因为Stack的大小有限,你可能想要在没有堆栈溢出错误的情况下搞乱大量的“整数”。

无论何时调用new,都应该在程序结束时“删除”,否则会出现内存泄漏,并且永远不会返回一些已分配的内存空间供其他程序使用。要做到这一点:

delete [] some_integers;

希望有所帮助。

答案 3 :(得分:7)

  

C ++中有一条规则,对于每个,都有删除

  1. 为什么第一个案例不起作用?似乎最直接的使用和删除指针?错误表示内存未分配,但'cout'返回了一个地址。
  2. 永远不会打电话给新人。因此,cout打印的地址是myVar的内存位置的地址,或者在这种情况下分配给myPointer的值。写下:

    myPointer = &myVar;
    
    你说:

      

    myPointer =存储myVar中数据的地址

    1. 在第二个示例中,没有触发错误但是执行myPointer值的cout仍会返回内存地址?
    2. 它返回一个指向已删除的内存位置的地址。因为首先创建指针并将其值分配给myPointer,然后再将其删除,第三步将其打印出来。因此,除非您为myPointer指定另一个值,否则删除的地址将保留。

      1. #3真的有效吗?似乎对我有用,指针不再存储地址,这是删除指针的正确方法吗?
      2. NULL等于0,删除0,因此不删除任何内容。它的逻辑是它打印0,因为你做了:

        myPointer = NULL;
        

        等于:

        myPointer = 0;
        

答案 4 :(得分:4)

  1. 您正在尝试删除堆栈上分配的变量。你不能这样做
  2. 删除指针实际上不会破坏指针,只是将占用的内存返回给操作系统。您可以访问它,直到内存用于另一个变量,或以其他方式操作。因此,最好在删除后将指针设置为NULL(0)。
  3. 删除NULL指针不会删除任何内容。

答案 5 :(得分:1)

int value, *ptr;

value = 8;
ptr = &value;
// ptr points to value, which lives on a stack frame.
// you are not responsible for managing its lifetime.

ptr = new int;
delete ptr;
// yes this is the normal way to manage the lifetime of
// dynamically allocated memory, you new'ed it, you delete it.

ptr = nullptr;
delete ptr;
// this is illogical, essentially you are saying delete nothing.