我应该删除指针吗?

时间:2017-03-02 01:08:40

标签: c++ pointers

所以我必须做一个项目,我需要实现arraylistbinary heapbinary treered-black tree然后衡量他们的表现,比较他们并得出一些结论。现在,规则是这样的:

  1. 必须使用C / C ++
  2. 无法使用std::(仅cout,可能是string),Boost
  3. 所以我迈出了第一步,实现了一个数组。它看起来像这样:

    array.h

    #pragma once
    #include <iostream>
    class array
    {
        int elements;
        int *table;
    public:
        array();
        array(int *t, int n);
        int size() const;
        int *get() const;
    };
    

    array.cpp

    #include "array.h"    
    
    array::array(int *t, int n) : elements(n), table(new int[elements])
    {   
        memcpy(table, t, elements * sizeof(int));
    }
    
    int array::size() const
    {
        return elements;
    }
    
    int *array::get() const
    {
        return table;
    }
    

    该程序基本上具有类似菜单的结构,使用简单的switch和5个不同的菜单进行5个竞赛。现在,我必须实现删除/添加元素,打印出数组等。我有一个代码将打印出一行数组:

    int *p = myArray.get();
    int s = myArray.size();
    std::cout << "[";
    for (int i = 0; i < myArray.size(); i++)
    {
        if (s - i == 1) std::cout << *(p + i) << "]" << '\n';
        else std::cout << *(p + i) << ", ";
    }
    delete p;
    

    我很好奇的是我写的最后一行。首先我没有使用delete,因为在这个代码块中没有任何地方存在new运算符。但后来我想,是的,它会导致内存泄漏,我已经添加了这条线。两种方式都有效。我的问题是:哪一个是正确的?在这种情况下,我是否应该删除pointer

3 个答案:

答案 0 :(得分:3)

&#39;删除&#39;一个指针将释放它指向的内存,无论它是一个副本还是原始的&#39;。这是因为它只保存一个内存地址(或内存地址的副本),而不是实际的内存。

此外,当您访问已释放的内存时,您无法保证返回给您的数据是您想要/期望的数据,因此您应该只在其所有者的析构函数中删除指针,或者您确定你不再需要它们了。

使用newnew[]时,您应始终使用正确的deletedelete[]对应方。

答案 1 :(得分:2)

只要您使用new(或new[]),就需要匹配delete(或delete[]),因此您需要删除{指向的数组{1}}某个地方。 array::table的析构函数通常是执行它的地方,因为array拥有该数据。这样,只要array超出范围,您的array数据就会被删除。请记住rule of three。如果您的类拥有某些资源,则应覆盖默认的复制构造函数,复制运算符和析构函数。

您似乎误解了array的作用。 delete删除动态分配的对象,而不是指针。执行delete后,您会遇到以下情况:

int *p = myArray.get();

当您致电+-----------+ | myArray | | +-------+ | +-------+ | | table | | | p | | +---+---+ | +-------+ +-----|-----+ | | +------+ | | +v-v-----------------------+ | allocated data | +--------------------------+ delete[] table时,您最终会得到以下信息:

delete[] p

+-----------+ | myArray | | +-------+ | +-------+ | | table | | | p | | +---+---+ | +-------+ +-----|-----+ | | +------+ | | v v Nothing here anymore, but the pointers still point here. myArray.table指向的数组都消失了,因此在指向用于保存该数组的内存的指针上调用p时的行为未定义。

答案 2 :(得分:0)

您可以考虑动态资源的所有权。

所有权意味着当没有人再使用它时,有人有责任释放它。如果你的array创建资源,最好让它在析构函数中由他自己释放。创建资源的人自然是所有者。

如果您打算让外面的人获得指针,int* p,并将其释放,delete p(应该是delete [] p),那么您将拥有所有权{{1 }}。您的p需要知道它不再拥有它,并且不允许array删除它。

当所有权明确明确时,资源泄露或双重删除的机会就会减少。

顺便说一下,这里有一些代码提示。

  • arrayp = new T配对; delete pp = new T[]
  • 配对
  • 首选使用delete p []来表示元素的数量。
  • 传递size_t可以使用int* t这样的常量。它不需要const int* t可变。