我试图用动态数组实现一个堆栈,并在代码分级器中对代码进行sumbit,但它总是给我带来分割错误。我想我可能在某个地方超出了数组的范围,但我无法解决。有什么想法吗?
#include <iostream>
using namespace std;
template <typename T>
class stack {
public:
int length;
T *data;
int top=0;
stack (int size) {
length=size;
data=new T[length]();
top=0;
}
stack (const stack &s) {
length=s.size();
data=new T[length]();
if(s.data!=NULL){
for(int i=0; i<length; i++){
data[i]=s.data[i];top++;
}}
}
~stack () {
if(data!=NULL){
delete[] data;}
data=NULL;
}
bool empty () {
return top==0;
}
void push (const T &x) {
data[top]=x;
top++;
}
T pop () {
return data[--top];
}
int size ()const{
return top;}
friend ostream & operator << (ostream &out,const stack &s) {
if(s.size()==0){
out<<"[]";}
else{
out<<'[';
for(int i=0; i<s.size()-1; i++){
out<<s.data[i]<<", ";
}
out<<s.data[s.size()-1]<<']';}
return out;
}
const stack & operator = (const stack &s){
top=s.top;
for(int i=0; i<length; i++){
data[i]=s.data[i];}
return *(this);
}
};
分级器对代码进行添加的示例如下:
#ifndef CONTEST
int main(){
stack<int> s(10);
cout << "s is empty: "<< s << endl;
s.push(42);
cout << "s has one element: " << s << endl;
s.push(17);
s.push(34);
cout << "s has more elements: " << s << endl;
cout << "How many? " << s.size() << endl;
stack<int> t(5);
t.push(7);
cout << "t: " << t << endl;
t = s;
cout << "popping from s: " << s.pop() << endl;
s.push(8);
stack<int> a(s);
t.push(99);
a.push(77);
cout << "s: " << s << endl;
cout << "t: " << t << endl;
cout << "a: " << a << endl;
// now with doubles...
stack<double> c(4);
c.push(3.14);
c.push(1.414);
cout << "c contains doubles " << c << endl;
// and with characters...
stack<char> k(4);
k.push('$');
cout << "k contains a character " << k << endl;
}
#endif
它应该输出这个:
s is empty: []
s has one element: [42]
s has more elements: [42, 17, 34]
How many? 3
t: [7]
popping from s: 34
s: [42, 17, 8]
t: [42, 17, 34, 99]
a: [42, 17, 8, 77]
c contains doubles [3.14, 1.414]
k contains a character [$]
您的复制分类运算符(operator=
(所做的事情与您的复制构造函数大不相同。事实上,它实际上并没有复制对象,只是复制data
中的元素。但在那里,它没有考虑不同数量的元素。
分配t = s;
导致分段故障。
const stack & operator = (const stack &s){
top=s.top; // s.top could be larger than the current size, no checks?
for(int i=0; i<length; i++) { //this->length == 10, but
data[i]=s.data[i];} //s.data contains only 7 elements!
return *(this);
}
从技术上讲,这是一种未定义的行为,幸运的是,它在这里表现为分段错误。
复制赋值运算符通常会做与复制构造函数相同的事情。一些参考链接和代码示例:5/3/0规则和什么是复制和交换习惯用法?
这是一个再现错误的最小代码:
int main() {
stack<int> s(10);
s.push(42);
stack<int> a(s);
a.push(77);
}
您的size
函数返回的只是top
,而不是size
:
int size()const {
return top;
}
因此,在您的复制构造函数中,您只为top elements
:创建空间
stack(const stack &s) {
length = s.size();
data = new T[length]();
//...
}
在你的情况下,你不能写:
a.push(77);
因为您分配了s.top
元素,而您的数组没有更多空间。您写出的债券会导致分割错误