Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于数组的堆栈-析构函数中出错 这是我C++的第一次可悲尝试。我在C++中做了一个基于数组的堆栈,析构函数抛出了一些内存转储。我不知道出了什么问题 #include <stdio.h> #include <iostream> #include <exception> using namespace std; class FullStackException : public exception { virtual const char* what() const throw() { return "Stack is full."; } } fsex; class EmptyStackException : public exception { virtual const char* what() const throw() { return "Stack is empty."; } } esex; template <class D> class ArrayBasedStack { private: int t; //t represents top D *S; int arrSize; public: ArrayBasedStack(int arraySize = 10); ~ArrayBasedStack(); int size(); /*returns the number of elements stored*/ void push(D&); /*inserts an element*/ D pop(); /*removes and returns the last inserted element*/ D top(); /*returns the last inserted element without removing it*/ int isEmpty(); /*indicates whether no elements are stored*/ }; template <class D> ArrayBasedStack<D>::ArrayBasedStack(int arraySize) { /* Elements are added from left to right */ S = new D[arraySize]; arrSize = arraySize; /* t keeps track of the index of the top element */ t = -1; } template <class D> ArrayBasedStack<D>::~ArrayBasedStack() { if(S != NULL) { int i = 0; for(i = 0; i < size(); i++) { S[i] = NULL; } cout << "about to delete S" << endl; delete[] S; } } template <class D> int ArrayBasedStack<D>::size() { return t; } template <class D> void ArrayBasedStack<D>::push(D& data) { if(t == arrSize) { throw fsex; } else { S[t] = data; t++; } } template <class D> D ArrayBasedStack<D>::pop() { if(isEmpty()) { throw esex; } D element = S[t]; S[t--] = NULL; return element; } /* * returns true if the stack is empty, false otherwise */ template <class D> int ArrayBasedStack<D>::isEmpty() { return (t < 0); } int main(int argc, char *argv[]) { char inputs[][10] = { "str1" }; char *i = NULL; ArrayBasedStack<char *> stack; i = inputs[0]; stack.push(i); try { stack.pop(); } catch(exception& ex) { cout << "ERR:" << ex.what() << endl; } return 0; } #包括 #包括 #包括 使用名称空间std; 类FullStackException:公共异常{ 虚拟常量char*what()常量throw(){ return“堆栈已满”; } }fsex; 类EmptyStackException:公共异常{ 虚拟常量char*what()常量throw(){ return“堆栈为空。”; } }esex; 模板 类ArrayBasedStack{ 私人: int t;//t表示顶部 D*S; 内角大小; 公众: ArrayBasedStack(int arraySize=10); ~ArrayBasedStack(); int size();/*返回存储的元素数*/ void push(D&);/*插入一个元素*/ D pop();/*删除并返回最后插入的元素*/ D top();/*返回最后插入的元素,而不删除它*/ int isEmpty();/*表示是否未存储任何元素*/ }; 模板 ArrayBasedStack::ArrayBasedStack(int-arraySize){ /*元素从左到右添加*/ S=新的D[排列]; arrSize=阵列化; /*t跟踪顶部元素的索引*/ t=-1; } 模板 ArrayBasedStack::~ArrayBasedStack(){ 如果(S!=NULL){ int i=0; 对于(i=0;i将参数作为 d const和< /Calp> 不确定这是多么可悲。这比我学习C++时做得好得多。):做得好。BTW——在析构函数和POP()中使用S[i] = NULL,但这并没有做任何特别有用的事。(对于D=char*,这确实意味着打印出整个堆栈可能允许对t进行双重检查,前提是您不推送(NULL))但是,它确实意味着任何类型的D,你必须实例化,它必须是NULL,这是一个相当大的和不必要的限制。在C++中,X = NULL不需要作为垃圾回收器的提示。你也可以安全地删除NULL,所以析构函数可以简单地删除[]。是的,但你对此保持谨慎是很自然的。+1,打败我。最佳实践是始终避免使用无效索引。代码需要更多的更改,而不仅仅是一个赋值。有些部分基于t超过顶部的假设,有些部分基于t是顶部的假设。_C++_Arrays_Stack_Adt - Fatal编程技术网

基于数组的堆栈-析构函数中出错 这是我C++的第一次可悲尝试。我在C++中做了一个基于数组的堆栈,析构函数抛出了一些内存转储。我不知道出了什么问题 #include <stdio.h> #include <iostream> #include <exception> using namespace std; class FullStackException : public exception { virtual const char* what() const throw() { return "Stack is full."; } } fsex; class EmptyStackException : public exception { virtual const char* what() const throw() { return "Stack is empty."; } } esex; template <class D> class ArrayBasedStack { private: int t; //t represents top D *S; int arrSize; public: ArrayBasedStack(int arraySize = 10); ~ArrayBasedStack(); int size(); /*returns the number of elements stored*/ void push(D&); /*inserts an element*/ D pop(); /*removes and returns the last inserted element*/ D top(); /*returns the last inserted element without removing it*/ int isEmpty(); /*indicates whether no elements are stored*/ }; template <class D> ArrayBasedStack<D>::ArrayBasedStack(int arraySize) { /* Elements are added from left to right */ S = new D[arraySize]; arrSize = arraySize; /* t keeps track of the index of the top element */ t = -1; } template <class D> ArrayBasedStack<D>::~ArrayBasedStack() { if(S != NULL) { int i = 0; for(i = 0; i < size(); i++) { S[i] = NULL; } cout << "about to delete S" << endl; delete[] S; } } template <class D> int ArrayBasedStack<D>::size() { return t; } template <class D> void ArrayBasedStack<D>::push(D& data) { if(t == arrSize) { throw fsex; } else { S[t] = data; t++; } } template <class D> D ArrayBasedStack<D>::pop() { if(isEmpty()) { throw esex; } D element = S[t]; S[t--] = NULL; return element; } /* * returns true if the stack is empty, false otherwise */ template <class D> int ArrayBasedStack<D>::isEmpty() { return (t < 0); } int main(int argc, char *argv[]) { char inputs[][10] = { "str1" }; char *i = NULL; ArrayBasedStack<char *> stack; i = inputs[0]; stack.push(i); try { stack.pop(); } catch(exception& ex) { cout << "ERR:" << ex.what() << endl; } return 0; } #包括 #包括 #包括 使用名称空间std; 类FullStackException:公共异常{ 虚拟常量char*what()常量throw(){ return“堆栈已满”; } }fsex; 类EmptyStackException:公共异常{ 虚拟常量char*what()常量throw(){ return“堆栈为空。”; } }esex; 模板 类ArrayBasedStack{ 私人: int t;//t表示顶部 D*S; 内角大小; 公众: ArrayBasedStack(int arraySize=10); ~ArrayBasedStack(); int size();/*返回存储的元素数*/ void push(D&);/*插入一个元素*/ D pop();/*删除并返回最后插入的元素*/ D top();/*返回最后插入的元素,而不删除它*/ int isEmpty();/*表示是否未存储任何元素*/ }; 模板 ArrayBasedStack::ArrayBasedStack(int-arraySize){ /*元素从左到右添加*/ S=新的D[排列]; arrSize=阵列化; /*t跟踪顶部元素的索引*/ t=-1; } 模板 ArrayBasedStack::~ArrayBasedStack(){ 如果(S!=NULL){ int i=0; 对于(i=0;i将参数作为 d const和< /Calp> 不确定这是多么可悲。这比我学习C++时做得好得多。):做得好。BTW——在析构函数和POP()中使用S[i] = NULL,但这并没有做任何特别有用的事。(对于D=char*,这确实意味着打印出整个堆栈可能允许对t进行双重检查,前提是您不推送(NULL))但是,它确实意味着任何类型的D,你必须实例化,它必须是NULL,这是一个相当大的和不必要的限制。在C++中,X = NULL不需要作为垃圾回收器的提示。你也可以安全地删除NULL,所以析构函数可以简单地删除[]。是的,但你对此保持谨慎是很自然的。+1,打败我。最佳实践是始终避免使用无效索引。代码需要更多的更改,而不仅仅是一个赋值。有些部分基于t超过顶部的假设,有些部分基于t是顶部的假设。

基于数组的堆栈-析构函数中出错 这是我C++的第一次可悲尝试。我在C++中做了一个基于数组的堆栈,析构函数抛出了一些内存转储。我不知道出了什么问题 #include <stdio.h> #include <iostream> #include <exception> using namespace std; class FullStackException : public exception { virtual const char* what() const throw() { return "Stack is full."; } } fsex; class EmptyStackException : public exception { virtual const char* what() const throw() { return "Stack is empty."; } } esex; template <class D> class ArrayBasedStack { private: int t; //t represents top D *S; int arrSize; public: ArrayBasedStack(int arraySize = 10); ~ArrayBasedStack(); int size(); /*returns the number of elements stored*/ void push(D&); /*inserts an element*/ D pop(); /*removes and returns the last inserted element*/ D top(); /*returns the last inserted element without removing it*/ int isEmpty(); /*indicates whether no elements are stored*/ }; template <class D> ArrayBasedStack<D>::ArrayBasedStack(int arraySize) { /* Elements are added from left to right */ S = new D[arraySize]; arrSize = arraySize; /* t keeps track of the index of the top element */ t = -1; } template <class D> ArrayBasedStack<D>::~ArrayBasedStack() { if(S != NULL) { int i = 0; for(i = 0; i < size(); i++) { S[i] = NULL; } cout << "about to delete S" << endl; delete[] S; } } template <class D> int ArrayBasedStack<D>::size() { return t; } template <class D> void ArrayBasedStack<D>::push(D& data) { if(t == arrSize) { throw fsex; } else { S[t] = data; t++; } } template <class D> D ArrayBasedStack<D>::pop() { if(isEmpty()) { throw esex; } D element = S[t]; S[t--] = NULL; return element; } /* * returns true if the stack is empty, false otherwise */ template <class D> int ArrayBasedStack<D>::isEmpty() { return (t < 0); } int main(int argc, char *argv[]) { char inputs[][10] = { "str1" }; char *i = NULL; ArrayBasedStack<char *> stack; i = inputs[0]; stack.push(i); try { stack.pop(); } catch(exception& ex) { cout << "ERR:" << ex.what() << endl; } return 0; } #包括 #包括 #包括 使用名称空间std; 类FullStackException:公共异常{ 虚拟常量char*what()常量throw(){ return“堆栈已满”; } }fsex; 类EmptyStackException:公共异常{ 虚拟常量char*what()常量throw(){ return“堆栈为空。”; } }esex; 模板 类ArrayBasedStack{ 私人: int t;//t表示顶部 D*S; 内角大小; 公众: ArrayBasedStack(int arraySize=10); ~ArrayBasedStack(); int size();/*返回存储的元素数*/ void push(D&);/*插入一个元素*/ D pop();/*删除并返回最后插入的元素*/ D top();/*返回最后插入的元素,而不删除它*/ int isEmpty();/*表示是否未存储任何元素*/ }; 模板 ArrayBasedStack::ArrayBasedStack(int-arraySize){ /*元素从左到右添加*/ S=新的D[排列]; arrSize=阵列化; /*t跟踪顶部元素的索引*/ t=-1; } 模板 ArrayBasedStack::~ArrayBasedStack(){ 如果(S!=NULL){ int i=0; 对于(i=0;i将参数作为 d const和< /Calp> 不确定这是多么可悲。这比我学习C++时做得好得多。):做得好。BTW——在析构函数和POP()中使用S[i] = NULL,但这并没有做任何特别有用的事。(对于D=char*,这确实意味着打印出整个堆栈可能允许对t进行双重检查,前提是您不推送(NULL))但是,它确实意味着任何类型的D,你必须实例化,它必须是NULL,这是一个相当大的和不必要的限制。在C++中,X = NULL不需要作为垃圾回收器的提示。你也可以安全地删除NULL,所以析构函数可以简单地删除[]。是的,但你对此保持谨慎是很自然的。+1,打败我。最佳实践是始终避免使用无效索引。代码需要更多的更改,而不仅仅是一个赋值。有些部分基于t超过顶部的假设,有些部分基于t是顶部的假设。,c++,arrays,stack,adt,C++,Arrays,Stack,Adt,问题线是 t = -1; 应该是 t = 0; 因为当您添加第一个元素时,下面的代码将被删除 } else { S[t] = data; // t == -1 t++; } 以下是罪魁祸首 template <class D> void ArrayBasedStack<D>::push(D& data) { if(t == arrSize) { throw fse

问题线是

    t = -1;
应该是

    t = 0;
因为当您添加第一个元素时,下面的代码将被删除

    } else {
       S[t] = data;    // t == -1
       t++;
    }

以下是罪魁祸首

template <class D> 
void ArrayBasedStack<D>::push(D& data) { 
    if(t == arrSize) { 
        throw fsex; 
    } else { 
        S[t] = data;       // Should be S[++t] = data;
        t++;               // Comment out this line
    } 
} 
模板
void ArrayBasedStack::推送(数据和数据){
如果(t==arrSize){
抛出fsex;
}否则{
S[t]=data;//应该是S[++t]=data;
t++;//注释掉这一行
} 
} 
此实现假定“t”指向堆栈上最顶层的元素,而不是
push的下一个可用位置

请注意,运算符[]和运算符++具有相同的优先级。因为它们从左到右关联,[]在运算符++之前求值

在您的实现中,这是一个问题。当t被初始化为-1时,您正在覆盖位于S[-1]的数组下标之外的内容,这将导致
未定义的行为

至少在我的系统上,当试图释放stack类的析构函数中的内存时,问题就出现了。这是一个典型的例子,说明在发生错误之后,syptom仍然可见


也会建议<代码>推< /Cord>将参数作为<代码> d const和< /Calp>

不确定这是多么可悲。这比我学习C++时做得好得多。):做得好。BTW——在析构函数和POP()中使用S[i] = NULL,但这并没有做任何特别有用的事。(对于D=char*,这确实意味着打印出整个堆栈可能允许对t进行双重检查,前提是您不推送(NULL))但是,它确实意味着任何类型的D,你必须实例化,它必须是NULL,这是一个相当大的和不必要的限制。在C++中,X = NULL不需要作为垃圾回收器的提示。你也可以安全地删除NULL,所以析构函数可以简单地删除[]。是的,但你对此保持谨慎是很自然的。+1,打败我。最佳实践是始终避免使用无效索引。代码需要更多的更改,而不仅仅是一个赋值。有些部分基于t超过顶部的假设,有些部分基于t是顶部的假设。