头文件(IntegerSet.h)
#include<iostream>
#include<string>
using namespace std;
class IntegerSet{
public:
unsigned int set[15];
unsigned int empty_set[15];
IntegerSet();
IntegerSet(int[],int);
IntegerSet unionOfsets(IntegerSet);
IntegerSet intersectionOfSets(IntegerSet);
void insertElement(int);
void deleteElement(int);
void printSet();
bool isEqualTo(IntegerSet);
void emptySet();//Set all elements of set to 0
void inputSet();//Reads values from the user into set
bool validEntry(int);//Determines a valid entry to the set
};
实施文件(IntegerSet.cpp)
//Class implementation file
#include "IntegerSet.h"
using namespace std;
IntegerSet::IntegerSet(){
for(int i=0;i<100;i++){
empty_set[i]=0;
}
}
IntegerSet::IntegerSet(int arr[],int size){
int min;//Use to hold the value for the sorting algorithm
int counter;//Used to count how many values need to be removed from the new array
for(int i=0;i<size-1;i++){//Nested for loop used to sort the array in ascending order
min=arr[i];
if(arr[i]<0||arr[i]>100){//If statement used to count how many numbers are <0 or >100
counter++;
}
for(int k=i+1;k<size;k++){
if(arr[k]<min){
arr[i]=arr[k];
arr[k]=min;
min=arr[i];
}
}
}
int *newSet=new int[size-counter];
for(int j=0;j<size;j++){
if(arr[j]>100||arr[j]<0){
//Do nothing
}else{
newSet[j]=arr[j];
}
}
delete newSet;
}
bool IntegerSet::validEntry(int a){
if(a<0||a>100){
return false;
}
return true;
}
void IntegerSet::inputSet(){
int a;
for(int i=0;i<100;i++){
cout<<"Enter an element(-1 to end)";
cin>>a;
if(a==-1){
cout<<"Entry complete";
return;
}
this->set[i]=a;
}
}
void IntegerSet::emptySet(){
for(unsigned int i=0;i<sizeof(this->set);i++){
this->set[i]=0;
}
}
IntegerSet IntegerSet::unionOfsets(IntegerSet a){
unsigned int *Union=new unsigned int[sizeof(this->set)+sizeof(a.set)];
for(unsigned int i=0;i<sizeof(this->set);i++){
*(Union+i)=this->set[i];
for(unsigned int h=0;h<sizeof(this->set);h++){
*(Union+(h+i))=a.set[h];
}
}
for(unsigned int j=0;j<sizeof(*Union);j++){
for(unsigned int z=j+1;z<sizeof(*Union);z++){
if(*(Union+j)==*(Union+z)){
*(Union+z)=0;
}
}
}
unsigned int newUnion[sizeof(*Union)];
for(unsigned int y=0;y<sizeof(*Union);y++){
if(*(Union+y)!=0&&y<sizeof(newUnion)){
newUnion[y]=*(Union+y);
}
}
IntegerSet c;
for(unsigned int w=0;w<sizeof(*Union);w++){
c.set[w]=newUnion[w];
}
delete Union;
return c;
}
IntegerSet IntegerSet::intersectionOfSets(IntegerSet a){
unsigned int *Intersect=new unsigned int[sizeof(this->set)+sizeof(a.set)];
int counter=0;
for(unsigned int i=0;i<sizeof(this->set);i++){
for(unsigned int j=0;j<sizeof(a.set);j++){
if(this->set[i]==a.set[j]){
*(Intersect+counter)=a.set[j];
counter++;
}
}
}
IntegerSet c;
for(unsigned int w=0;w<sizeof(*Intersect);w++){
c.set[w]=*(Intersect+w);
}
delete Intersect;
return c;
}
void IntegerSet::printSet(){
unsigned int min;
for(unsigned int i=0;i<sizeof(this->set)-1;i++){
min=this->set[i];
for(unsigned int k=i+1;k<sizeof(this->set);k++){
{
if(this->set[k]<min){
this->set[i]=this->set[k];
this->set[k]=min;
min=this->set[i];
}
}
}
cout<<"{";
for(unsigned int h=0;h<3;h++){
if(h==sizeof(this->set)-1){
cout<<this->set[h]<<"}";
}else{
cout<<this->set[h]<<",";
}
}
}
bool IntegerSet::isEqualTo(IntegerSet a){
unsigned int counter=0;
if(sizeof(a.set)==sizeof(this->set)){
for(unsigned int i=0;i<sizeof(this->set);i++){
for(unsigned int f=0;f<sizeof(a.set);f++){
if(this->set[i]==a.set[f]){
counter++;
}
}
}
}else{
return false;
}
if(counter==sizeof(this->set)){
return true;
}
return false;//Used to make sure this method always has something to return
}
void IntegerSet::insertElement(int a){
unsigned A=(unsigned)a;
if(!this->validEntry(a)){
cout<<"Invalid Insertion Attempt!";
}
unsigned int Inserted[sizeof(this->set)+1];
Inserted[sizeof(this->set)]=A;
for(unsigned int w=0;w<sizeof(Inserted);w++){
this->set[w]=Inserted[w];
}
}
void IntegerSet::deleteElement(int a){
unsigned A=(unsigned) a;
unsigned int *Delete=new unsigned int[sizeof(this->set)-1];int test=0;
if(!this->validEntry(a)){
cout<<"No value of: "<<a<<" exists in the set";
}
for(unsigned int z=0;z<sizeof(this->set);z++){
if(this->set[z]==A){
test++;
}
}
if(test==0){
cout<<"No value of: "<<a<<" exists in the set";
}
for(unsigned int i=0;i<sizeof(this->set)-1;i++){
*(Delete+i)=this->set[i];
}
for(unsigned int w=0;w<sizeof(*Delete);w++){
this->set[w]=*(Delete+w);
}
delete Delete;
}
然后是我的测试人员文件,这是让我找到错误的原因 (IntSet.cpp)
//Driver program for class IntegerSet
#include <iostream>
using namespace std;
#include "IntegerSet.h"
int main(){
IntegerSet a,b,c,d;
cout<<"Enter set A:\n";
a.inputSet();
cout<<"\nEnter set B:\n";
b.inputSet();
c=a.unionOfsets(b);
d=a.intersectionOfSets(b);
cout<<"\nUnion of A nd B is:\n";
c.printSet();
cout<<"Intersection of A nd B is:\n";
d.printSet();
//Test if set A is equal to set B
if(a.isEqualTo(b)){
cout<<"Set A is equal to set B\n";
}else{
cout<<"Set A is not equal to set B\n";
}
//test insertion
cout<<"\nInserting 77 into set A...\n";
a.insertElement(77);
cout<<"Set A is now:\n";
a.printSet();
const int arraySize=10;
int intArray[arraySize]={25,67,2,9,99,105,45,-5,100,1};
//Use construct that receive an array of ints
//and the size of that array to create a set object
IntegerSet e(intArray,arraySize);
cout<<"\nSet e is:\n";
e.printSet();
cout<<endl;
}
就我个人而言,我觉得导致这个错误的原因是某种内存泄漏,虽然glib c错误并没有像编译器那样准确地告诉我它将来自何处。此函数也会在函数b.inputSet()退出后立即发生。
错误说的是什么(它在我注意到的两条消息之间交替出现):
***glibc detected*** ./a.out: free(): invalid next size (normal):
***glibc detected*** ./a.out: double free or corruption (!prev):
答案 0 :(得分:1)
你在这里做得很多。
以下是empty_set
的定义。
unsigned int empty_set[15];
你的默认构造函数访问这些边界之外。
IntegerSet::IntegerSet(){
for(int i=0;i<100;i++){
empty_set[i]=0;
}
}
你的其他构造函数实际上没有改变类中的任何内容。
此代码
IntegerSet IntegerSet::unionOfsets(IntegerSet a){
unsigned int *Union=new unsigned int[sizeof(this->set)+sizeof(a.set)];
看起来非常可疑,因为sizeof(set)
不是集合中的元素数量,而是数组长度(以字节为单位)(15 * sizeof(float)) - 但如果切换到可变长度数组,它甚至不会......您需要分别跟踪设定的长度。或者使用std::vector<int>
,或者更好 - 为什么重新发明轮子并使用std::set<int>
?
答案 1 :(得分:0)
删除数组时,需要告诉delete它是一个数组
所以
int *newSet = new int[size - counter];
需要使用
删除delete[] newSet;
可能还有几个。这是我发现的第一个。
当你有时间时,请查看Valgrind工具。它会给出非常详细的结果。