Ошибка сборки, но нет ошибок компиляции

У меня проблемы с домашним заданием, и я могу воспользоваться вашей помощью.

Я получаю какую-то ошибку, когда пытаюсь запустить свою программу. Когда я компилирую его, я получаю сообщение об успехе, но когда я пытаюсь его запустить, я получаю всплывающее окно с ошибкой «Необработанное исключение в 0x011b18d2 в Project 2.exe: 0xC0000005: Место чтения нарушения доступа 0xccccccd0». Если кто-нибудь может мне помочь, я был бы признателен, спасибо.

Это код, на который я был назначен (это нельзя изменить)

#include <iostream >
#include "stack.h"using namespace std ;
int main ()
{
Stack < int > s1 , s2 ;
int element ;

s1 . push (1); s1 . push (2); s1 . push (3);
s1 . pop ( element );
cout << " s1 popped element : " << element << endl ;

s2 = s1 ;
s2 . push (4);
s2 . pop ( element );
cout << " s2 popped element : " << element << endl ;

s1 . pop ( element );
cout << " s1 popped element : " << element << endl ;

s2 . makeEmpty ();
s2 . isEmpty () ? cout << " s2 is empty \n": cout << " s2 is not empty \n ";

system ("pause");
return 0;
}

Это то, что я написал, чтобы дополнить код выше

template <class DataType>
struct Node{
DataType info;
Node<DataType>*next;
};

template <class DataType>
class Stack
{
public:
Stack();
void push(DataType elementToPush);
bool pop(DataType & poppedElement);
bool peek(DataType & topElement);
Stack(const Stack<DataType> &element); // Copy constructor
~Stack(); // Destructor
Stack<DataType> & operator=(const Stack<DataType> &element); //Overload assignment operator
bool isEmpty()const;
void makeEmpty();
private:
Node<DataType>*top;
Node<DataType>*header;
inline void deepCopy(const Stack<DataType> & original);
};

template<class DataType>
Stack<DataType>::Stack()
{
Node<DataType>*top=new Node<DataType>;
}

template<class DataType> // Remove the node at the front of the list and return the element
bool Stack<DataType>::pop(DataType & poppedElement)
{
Node<DataType>*ptr=top;
ptr=ptr->next;
Node<DataType>*ptr2=ptr->next;
top->next=ptr2;
poppedElement = ptr->info;
delete ptr;
return true;
}

template<class DataType> // Return the element at the front of the list wothout deleting it
bool Stack<DataType>::peek(DataType & topElement)
{
if(top->next==NULL)
return false;
topElement=top->next->info;
return true;
}

template<class DataType> // Make a new node for the element and push it to the front of the list
void Stack<DataType>::push(DataType elementToPush)
{
Node<DataType>*ptr=top;
Node<DataType>*ptr2=new Node<DataType>;
ptr2->info=elementToPush;
ptr2->next=ptr->next;
ptr->next=ptr2;
}

template<class DataType> // Check to see if the list is empty
bool Stack<DataType>::isEmpty()const
{
return top->next==NULL;
}

template<class DataType> // Empry the list out
void Stack<DataType>::makeEmpty()
{
Node<DataType>*ptr=top;
while(top->next != NULL)
{
while(ptr->next != NULL)
ptr->next;
delete ptr->next;
}
}

template<class DataType> // Deep copy
inline void Stack<DataType>::deepCopy(const Stack<DataType> & original)
{
Node<DataType>*copyptr=new Node<DataType>;
Node<DataType>*originalptr=top;
while(originalptr != NULL)
{
originalptr=originalptr->next;
copyptr->next=new Node<DataType>;
copyptr->info=originalptr->info;
}
}

template<class DataType> // Copy Constructor
Stack<DataType>::Stack(const Stack<DataType> &element)
{
deepCopy(element);
}

template<class DataType> // Destructor
Stack<DataType>::~Stack()
{
makeEmpty();
}

template<class DataType> // Overload assignment operator
Stack<DataType> & Stack<DataType>::operator=(const Stack<DataType> &element)
{
if(this == &element)
return *this;
makeEmpty();
deepCopy(element);
return *this;
}

-3

Решение

Я получил откат на мой предыдущий ответ. Может быть, этот будет лучше принят. Если вам не нравится мой выбор пустого пространства, это то, для чего нужны симпатичные принтеры. Код ниже представляет собой исходный код переформатирован. Мои мысли включены как межлинейный глянец.

Node это деталь реализации вашего Stack, Это должно быть определено как закрытое объявление типа, размещение здесь загрязняет пространство имен. Кроме того, если этот класс имеет конструктор, который либо инициализируется next в nullptr или если бы он был задан явно, некоторые ошибки, такие как обнаруженная вами, было бы легче диагностировать. Как это стоит, после Node построен, next может указывать на случайную ячейку памяти.

template <class DataType>
struct Node {
DataType info;

Рассмотрите возможность использования умного указателя здесь.

  Node<DataType>* next; };

template <class DataType>
class Stack {
public:
Stack();

Аргумент должен быть const& чтобы избежать лишнего копирования.

  void push(DataType elementToPush);
bool pop(DataType& poppedElement);

Это может быть const метод.

  bool peek(DataType& topElement);

element это плохое имя. Конструктор копирования копирует весь стек, а не только элемент.

  Stack(const Stack<DataType>& element); // Copy constructor
~Stack(); // Destructor
Stack<DataType>& operator=(const Stack<DataType>&
element);  //Overload assignment operator
bool isEmpty() const;
void makeEmpty();
private:

Рассмотрите возможность использования умного указателя здесь.

  Node<DataType>* top;

header не используется Это должно быть удалено.

  Node<DataType>* header;
inline void deepCopy(const Stack<DataType>& original); };

template<class DataType>
Stack<DataType>::Stack() {

top следует инициализировать в nullptr в списке инициализации члена. Пустой узел вы
использование здесь не обязательно, это делает ваш код более сложным, и вы в конечном итоге пропускаете его позже.

Кроме того, это серьезная ошибка. Вы назначаете здесь локальную, а не переменную-член!

  Node<DataType>* top = new Node<DataType>; }

template<class DataType> // Remove the node at the front of the list and return the element
bool Stack<DataType>::pop(DataType& poppedElement) {

Если ты хочешь ptr быть top->next просто скажи это.

  Node<DataType>* ptr = top;
ptr = ptr->next;

это ptr2 переменная не нужна. Вам просто нужно top->next = top->next->next, Также обратите внимание, что пустой элемент head добавляет здесь шум.

  Node<DataType>* ptr2 = ptr->next;
top->next = ptr2;
poppedElement = ptr->info;
delete ptr;

Вы должны проверить на предмет недостаточного возврата для возврата false в таком случае.

  return true; }

Люди довольно прощают комментарии, но лучше, если они правильно написаны и отмечены пунктуацией.

template<class DataType> // Return the element at the front of the list wothout deleting it
bool Stack<DataType>::peek(DataType& topElement) {
if (top->next == NULL) {
return false; }

topElement = top->next->info;
return true; }

template<class DataType> // Make a new node for the element and push it to the front of the list
void Stack<DataType>::push(DataType elementToPush) {

Эта переменная не имеет смысла, просто используйте top,

  Node<DataType>* ptr = top;

ptr2 может быть создан со значениями, которые вам нужны, вместо того, чтобы быть впоследствии видоизмененным Пытаться auto ptr2 = new Node<DataType> { elementToPush, ptr->next };, Также рассмотрите возможность использования умного указателя.

  Node<DataType>* ptr2 = new Node<DataType>;
ptr2->info = elementToPush;
ptr2->next = ptr->next;
ptr->next = ptr2; }

template<class DataType> // Check to see if the list is empty
bool Stack<DataType>::isEmpty()const {
return top->next == NULL; }

Эта функция просто сломана. Вы должны переосмыслить это.

template<class DataType> // Empry the list out
void Stack<DataType>::makeEmpty() {
Node<DataType>* ptr = top;

while (top->next != NULL) {

Один while петля сделает тебя. Списки линейные, а не квадратные.

    while (ptr->next != NULL) {

Это утверждение не имеет никакого эффекта; это ничего не делает. Ваш компилятор должен предупреждать об этом, включать предупреждения или увеличивать уровень предупреждения.

      ptr->next; }

delete ptr->next; } }

Это тоже очень сломано. Вам нужно перебрать два списка, поэтому вам нужны две переменные итератора. Один итератор — это то, что вы копируете, и вам просто нужно его скопировать во время чтения. Другой видоизменяет текущий объект и имеет немного больше бухгалтерского учета.

template<class DataType> // Deep copy
inline void Stack<DataType>::deepCopy(const Stack<DataType>& original) {
Node<DataType>* copyptr = new Node<DataType>;
Node<DataType>* originalptr = top;

while (originalptr != NULL) {
originalptr = originalptr->next;
copyptr->next = new Node<DataType>;
copyptr->info = originalptr->info; } }

template<class DataType> // Copy Constructor
Stack<DataType>::Stack(const Stack<DataType>& element) {
deepCopy(element); }

template<class DataType> // Destructor
Stack<DataType>::~Stack() {

Обратите внимание, что makeEmpty не удаляет ваш пустой головной узел. Это приведет к утечке узла.

  makeEmpty(); }

template<class DataType> // Overload assignment operator
Stack<DataType>& Stack<DataType>::operator=(const Stack<DataType>&
element) {
if (this == &element) {
return *this; }

makeEmpty();

Опять же, ваш пустой головной узел вызывает здесь боль. Есть ли deepCopy создать пустой головной узел или нет? Ваше использование этого в вашем конструкторе копирования, кажется, предполагает, что это делает. Ваше использование этого здесь, кажется, предполагает, что это не так. На самом деле, я думаю, что проблема в том, что makeEmpty не удаляет ваш головной узел, в противном случае эта функция и ваш деструктор будут работать правильно.

  deepCopy(element);
return *this; }
1

Другие решения

То, что вы видите, это ошибка времени выполнения, а не ошибка сборки. И ваша IDE сообщает об успешной сборке, а не ваш отладчик. Ваш отладчик — это то, что позволяет вам построчно прослеживать программу и проверять значения ваших переменных.

Сравните ваш код со следующим.

template <class DataType>
struct Node {
DataType info;
Node<DataType>* next; };

template <class DataType>
class Stack {
public:
Stack();
void push(DataType elementToPush);
bool pop(DataType& poppedElement);
bool peek(DataType& topElement);
Stack(const Stack<DataType>& element);
~Stack();
Stack<DataType>& operator=(const Stack<DataType>& element);
bool isEmpty()const;
void makeEmpty();
private:
Node<DataType>* top;
inline void deepCopy(const Stack<DataType>& original); };// Linked list stack implementation.
template<class DataType>
Stack<DataType>::Stack() {
// Head of the list. Not actually used for anything. Why is this here?
top = new Node<DataType>; }

// Remove the node at the front of the list and return the element
// Does not check for underflow.
template<class DataType>
bool Stack<DataType>::pop(DataType& poppedElement) {
Node<DataType>* ptr = top->next;
Node<DataType>* ptr2 = ptr->next;
top->next = ptr2;
poppedElement = ptr->info;
delete ptr;
return true; }

// Return the element at the front of the list without deleting it
template<class DataType>
bool Stack<DataType>::peek(DataType& topElement) {
if (top->next == NULL) {
return false; }

topElement = top->next->info;
return true; }

// Make a new node for the element and push it to the front of the list
template<class DataType>
void Stack<DataType>::push(DataType elementToPush) {
Node<DataType>* ptr2 = new Node<DataType>;
ptr2->info = elementToPush;
ptr2->next = top->next;
top->next = ptr2; }

// Check to see if the list is empty
template<class DataType>
bool Stack<DataType>::isEmpty()const {
return top->next == NULL; }

// Empty the list out
template<class DataType>
void Stack<DataType>::makeEmpty() {
while (top->next != NULL) {
Node<DataType>* ptr = top->next;
top->next = ptr->next;
delete ptr; } }

// Deep copy
template<class DataType>
inline void Stack<DataType>::deepCopy(const Stack<DataType>& original) {
Node<DataType>* origiter = original.top;
Node<DataType>* thisiter = top;

while (origiter->next != NULL) {
thisiter->next = new Node<DataType>(*(origiter->next));
origiter = origiter->next;
thisiter = thisiter->next; }

thisiter->next = NULL; }

// Copy Constructor
template<class DataType>
Stack<DataType>::Stack(const Stack<DataType>& element) {
deepCopy(element); }

// Destructor
template<class DataType>
Stack<DataType>::~Stack() {
// This leaks because the head node is still there.
makeEmpty(); }

// Overload assignment operator
template<class DataType>
Stack<DataType>& Stack<DataType>::operator=(const Stack<DataType>&
element) {
if (this == &element) {
return *this; }

makeEmpty();
deepCopy(element);
return *this; }
-1

По вопросам рекламы [email protected]