【发布时间】:2015-05-28 03:04:53
【问题描述】:
头文件(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):
【问题讨论】:
-
Valgrind 在这些情况下非常有用。
-
“我个人觉得导致这个错误的原因是某种内存泄漏”——你的感觉完全不正确。在你有几年的经验之前,你应该拒绝关注自己的感受。
-
这段代码有很多错误。我建议你在上面运行一个静态分析器,看看它抱怨什么。或者在此处将标头和实现复制并粘贴到在线检查器(DIY-C++ 选项)中:gimpel-online.com/OnlineTesting.html
-
仅供参考 - 我在代码上运行了该检查器并收到了几页警告,其中大部分是关于
[]的无效范围。但我不会把它们都贴在这里... -
@MichaelAnderson 当我将头文件和实现文件复制并粘贴到在线检查器中时,它是否必须按任何特定顺序排列?它们是否都被粘贴到同一个区域中?谢谢你的帮助!抱歉,如果我问的问题太多。
标签: c++ class memory-leaks runtime-error glibc