删除C ++中的对象和新关键字

时间:2013-06-03 00:54:02

标签: c++ memory delete-operator

几个问题:

我在www.cprogramming.com上查看以下代码以获取链接列表:

struct node {
  int x;
  node *next;
};

int main()
{
  node *root;      // This will be the unchanging first node

  root = new node; // Now root points to a node struct
  root->next = 0;  // The node root points to has its next pointer
                   //  set equal to a null pointer
  root->x = 5;     // By using the -> operator, you can modify the node
                   //  a pointer (root in this case) points to.
}
  1. 此代码是否会导致[小]内存泄漏,因为他最后从不删除root?

  2. 另外,如果'node'是一个类而不是一个struct,这会有什么不同吗?

  3. 最后,对于这段代码:

    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
    A(){}
    void sing()
    { cout << "TEST\n";}
    };
    
    int main()
    {
    A *a = new A();
    a->sing();
    return 0;
    }
    
    1. 我必须在退出main之前删除A吗?
    2. 在什么情况下我会使用A *a = new A()而不是A a = A()

4 个答案:

答案 0 :(得分:2)

1.1是的,虽然在任何现代操作系统上,当进程结束时,操作系统会回收所有内存。内存泄漏对于长期存在的进程来说是一个大问题,在这些进程中,内存不断泄漏,并且该进程继续要求更多内存,无明显原因。

1.2我想你的意思是class,而不是一个对象(一个对象是一个类或一个结构的实例)......但是,没有区别,class和{ {1}}仅在默认访问说明符方面有所不同(structpublicstructprivate

2.1是(与1.1中的警告相同)。

2.2通常当(a)class太大而无法放在堆栈上时,(b)当局部变量强加的对象生命周期(=范围末尾的自动销毁)不合适时, (c)在编译时不知道要创建的对象数。

示例:

一个。 A在其定义中包含一个非常大的矩阵,它会占用大量的堆栈空间;或者,A不是那么大,但当前的调用是递归的,所以把它放在堆栈上可能会导致堆栈溢出。

A是从此函数返回的对象(并且不接受副本);或者,A将在此函数中创建,并在将来被其他函数删除,但不会在当前范围的末尾删除。

℃。 A是链接列表的节点,用于填充用户提供的数据;您可以在循环中创建和附加节点,直到用户提供数据结束。

答案 1 :(得分:2)

第一部分:

  1. 它可能很草率(像Valgrind这样的工具会警告它),但当main返回时,操作系统会释放所有内存。如果程序继续运行,内存泄漏就会持续存在。
  2. C ++在“类”和“结构”之间没有区别。 class只是将其初始访问权限修改为私有而非公开。
  3. 以后的部分:

    1. 与1相同。
    2. 这是一个相当复杂的问题。从广义上讲,在对象需要比当前范围更长的情况下(例如,由构造它的函数返回)或者它的大小,你将需要使用堆内存分配(这是new所做的)。由于其他原因,动态确定或可能非常大。

答案 2 :(得分:1)

  

这段代码是否会导致[小]内存泄漏,因为他最后从不删除root?

是的,但是程序终止并且操作系统应该回收内存。所以任何内存泄漏检查都会标记这一点。

  

另外,如果'node'是一个对象而不是一个struct?

,这会有什么不同吗?

没有。除了结构的默认保护是public

之外,结构和类几乎相同
  

我必须在退出main之前删除A吗?

是。避免内存泄漏。

  

在什么情况下我会使用A * a = new A()而不是使用A a = A()?

使用operator new将在堆上分配内存。它最好在堆栈上分配,除非你需要你的对象超过堆栈帧的生命周期,在这种情况下你可以通过复制返回,或者在堆上分配它,它将一直保留到删除之前。

答案 3 :(得分:0)

第一部分

1)是的,存在内存泄漏。

2)类和结构之间没有功能差异。

第二部分

1)是的,您应该删除在堆上分配的任何对象。

2)在任何你可以避免指针(并分配堆内存)的情况下,你应该这样做。它需要更少的时间并使用更少的资源来使用堆栈。 在这种情况下,对象的生命周期很短,因此使用堆是没有意义的。