构建时出错但没有编译错误

时间:2014-10-21 18:42:39

标签: c++

我的作业有些麻烦,可以使用你的帮助。

当我尝试运行程序时,我遇到了一些错误。当我编译它时,我获得成功消息,但是当我尝试运行它时,我得到一个错误的弹出窗口"项目2.exe中的0x011b18d2处的未处理异常: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;
}    

2 个答案:

答案 0 :(得分:1)

我的回答是我的回答。也许这个会更好。如果你不喜欢我选择的空白区域,那就是漂亮的打印机。下面的代码是重新格式化的原始代码。我的想法包含在线性光泽中。

NodeStack的实施细节。它应该作为私有类型声明的范围,在这里污染命名空间。此外,如果此类具有初始化nextnullptr或要求明确设置它的构造函数,则某些错误(例如您找到的错误)将更容易诊断。就目前而言,构建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。另请注意,空头元素会在此处添加噪声。

  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 :(得分:-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; }