2017-02-12 11 views
1

Прежде всего, я прошу прощения за этот вопрос. Я рассмотрел большинство основных ответов, связанных с delete и new в C++, но я по-прежнему не могу исправить свои проблемы здесь. Здесь у меня есть 3 класса следующим образом:Правильное использование delete в C++

class bucket 
{ 
    // Some stl container here where data would be inserted 
    // Some methods and fields here 
    // This class has no new keyword 
}; 

class TrieNode 
{ 
    public: 
    bucket *pointer; 
    TrieNode() //Constructor for this class 
    { 
     pointer = NULL; 
    }; 
    TrieNode(int local) //Parametrized Constructor for this class 
    { 
     pointer = new bucket(local); //Here is the new keyword 
    } 
}; 

class Hashtable 
{ 
    private: 
    int globalDepth; 
    std::vector<TrieNode> table; //Vector of other class 

    void Split(int index) 
    { 
    // Here I am creating instances of other class(TrieNode) which has pointer 
     TrieNode first(capacity); 
     TrieNode second(capacity); 
    // Then after some processing I have to do this 
     table[index] = first; //Assignment which will be using new keyword in it's class i.e. first 
     table[mirrorIndex] = second; //again assignment 
    } 
public: 
    Hashtable(int globalDepth) //Constructor for this class 
    { 
     std::cout<<"Table is being created...\n"; 
     this->globalDepth = globalDepth; 
     table.resize(pow(2,globalDepth),TrieNode()); //vector of class here 
    } 
}; 

int main(int argc, char const *argv[]) 
{ 
    bool input = true; 
    Hashtable mytable(1); //Instance of Third class 
} 

Теперь моя проблема, когда я использую деструктор в классе TrieNode с delete pointer он показывает мне Сегментация ошибку, как только я пытаюсь вставить что-то в векторе класса С потому что destructor вызывается автоматически после создания и удаляет вектор [right?], и когда я использую delete в деструкторе класса C как delete table[i].pointer, тогда я также получаю ошибку [core dumped]. Итак, как я должен использовать delete в этих случаях. Случаи, когда я использовал назначение экземпляра класса (с новым) внутри некоторых функций, например. в функции Split выше в классе C Или мне нужно изменить общий стиль здесь?

+1

Научитесь использовать gdb и читайте о std :: unique_ptr и создайте копии (что они на самом деле копируют) – James

+0

@James Конечно. Благодаря! –

ответ

0
class TrieNode 
{ 
    public: 
    bucket *pointer; 
    TrieNode() //Constructor for this class 
    { 
     pointer = NULL; 
    } 
    ~TrieNode() //destructor for this class 
    { 
     pointer = NULL; 
delete pointer; 
    } 
    TrieNode(int local) //Parametrized Constructor for this class 
    { 
     pointer = new bucket(local); //Here is the new keyword 
    } 
}; 

Где вы определили потенциал? Существует ';' после определения конструктора, который я удалил. Деструктор вашего класса просто должен удалить объект, выделенный в куче с новым, компилятор позаботится о том, чтобы уничтожить все локальные переменные, вы беспокоитесь только о том, что такое куча.

Hashtable(int nGlobalDepth) //Constructor for this class 
    { 
     std::cout<<"Table is being created...\n"; 
     this->globalDepth = nGlobalDepth; 
     table.resize(pow(2,globalDepth),TrieNode()); //vector of class here 
    } 

Имея переменную с точно таким же именем, как в качестве члена класса и в качестве аргумента функции с помощью элемента указанного класса является плохой практикой, у вас есть несколько вариантов (можно использовать «_» префикс для переменной-члена класса или переименовать аргумент)

+0

Я не показал полный код всех классов и методов. 'capacity' - это один' int', определенный внутри метода. Я проверю этот код и отвечу вам, как только закончите. Спасибо, кстати, и один вопрос, почему вы делаете «указатель NULL», а затем «удаляете» его. Какую цель он будет выполнять? –

+0

@SunilKumar Ошибка удаления указателя перед удалением – James

+0

Использование вашего предложения в векторе будет прерываться, поскольку TrieNode не соответствует правилу-тройке –

1

TrieNode экземпляр имеет свой pointer экземпляр типа bucket, поэтому он отвечает за освобождение его, вызывая delete в деструкторе. Поэтому сначала нужно добавить что-то вроде:

~TrieNode() 
{ 
    delete pointer; 
} 

(Обратите внимание, что pointer, вероятно, не великое имя для переменной, поскольку она указывает на его тип, а не его использования Рассмотрим data или что-то..)

Тогда, когда удаляется TrieNode, также будет указатель на ведро. Вы можете позвонить delete безопасно на nullptr, и он просто ничего не сделает, поэтому нет необходимости проверять, установлен ли pointer.

Поскольку хэш-таблица использует экземпляры std::vector<TrieNode>, вектор будет содержать (и собственный) экземпляр объекта. Таким образом, удаление экземпляра, удаление HashTable и т. Д. Должно быть правильно очищено.

Одна из потенциальных проблем - создать экземпляр TrieNode, а затем передать его HashTable. Это сделает мелкую копию объекта (так как вы не определили конструктор копирования), и, таким образом, у вас будет два объекта, указывающих на одно и то же ведро в куче. Когда первый экземпляр будет уничтожен, ведро будет удалено. Но тогда, когда второй экземпляр будет уничтожен, он также попытается удалить ведро во второй раз и вызвать сбой. Я подозреваю, что это объясняет проблемы, которые вы описываете.

В общем случае, если ваш класс динамически распределяет память, он должен иметь деструктор и конструктор копирования, чтобы память управлялась правильно.Попытайтесь сделать работу/удалить работу симметрично, поэтому вещь, которая владеет памятью (вызовы new) также delete. Хэш-таблица не должна «доходить» до объекта trie и удалять память от ее имени.

Как отмечалось выше, JJames, вероятно, стоит использовать интеллектуальные указатели и позволить компилятору и библиотеке выполнять эту работу за вас.

 Смежные вопросы

  • Нет связанных вопросов^_^