I created a program that use a dynamic array. It works, when i use my insert function and then i show the elements of the arrays, it show me all what i want. The problem is that at the end of the program it doesn't return with value 0, but it is blocked for a few second and say "Process exited with value 3221225477". What is wrong?
header:
#ifndef VETTORE_H
#define VETTORE_H
#include "regalo.h"
typedef regalo T;
class vettore {
friend ostream& operator<<(ostream&,const vettore&);
friend istream& operator>>(istream&,vettore&);
private:
T *v;
int riemp;
int max;
public:
vettore();
vettore(const int);
~vettore(){delete [] v;};
bool full(){return riemp==max;};
bool empty()const;
bool inserisci(const T&);
T& operator[](const int index);
};
#endif
cpp file:
#include "vettore.h"
ostream &operator<<(ostream& out,const vettore & v1){
for(int i=0;i<v1.riemp;i++){
out<<v1.v[i];
}
return out;
}
istream &operator>>(istream& in,vettore &v1){
for(int i=0;i<v1.riemp;i++){
in>>v1.v[i];
}
return in;
}
vettore::vettore(){
riemp=0;
max=10;
v=new T[max];
}
vettore::vettore(const int n):max(n),riemp(0){
v=new T[max];
}
bool vettore::empty()const{
if(riemp==0){
return true;
}else return false;
}
bool vettore::inserisci(const T& n){
if(max==0){
cout<<"Inserisci il massimo di elementi del vettore: ";
cin>>max;
}
if(!full()){
v[riemp]=n;
riemp++;
return true;
}else return false;
}
T& vettore::operator[](const int index){
return v[index];
}
main file:
#include "vettore.h"
int main(int argc, char** argv) {
int riempimento;
vettore vett(1);
regalo r1("Alex",300,"quadrato");
vett.inserisci(r1);
cout<<"Gli elementi del vettore sono: \n";
for(int i=0;i<riempimento;i++){
cout<<vett[i]<<endl;
}
system("PAUSE");
return 0;
}
There are a few issues in your code:
riempimento is not initialised so the for loop in main will perform an unknown number of iterations, likely more than the size of your vector. It would be better to expose the value of riemp from inside the vector and use that in the loop instead.
You need to implement the rule of three, this isn't causing you a problem yet but will in the future if you copy your vettore objects.
If max is 0 when you call inserisci you prompt the user for a value of max, you don't check that cin succeeds and you don't reallocate v to be large enough to contain max elements.
Not a problem but empty could simply be implemented as:
bool vettore::empty()const{
return riemp==0;
}
Related
Header File (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
};
Implementation File (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;
}
And then there is my tester file, which is what allowed me to find the error
(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;
}
Personally I feel like what caused this error was some sort of memory leak, although the glib c error isn't exactly telling me where it would be coming from like the compiler does. Also this error occurs right after the function b.inputSet() exits.
What the error says (it alternates between two messages I've noticed):
***glibc detected*** ./a.out: free(): invalid next size (normal):
***glibc detected*** ./a.out: double free or corruption (!prev):
You're doing lots of bad here.
Here's your definition of empty_set.
unsigned int empty_set[15];
And your default constructor accesses outside these bounds.
IntegerSet::IntegerSet(){
for(int i=0;i<100;i++){
empty_set[i]=0;
}
}
Your other constructor doesn't actually change anything inside the class.
Also this code
IntegerSet IntegerSet::unionOfsets(IntegerSet a){
unsigned int *Union=new unsigned int[sizeof(this->set)+sizeof(a.set)];
looks remarkably suspicious as sizeof(set) is not the number of elements in set, but the array length in bytes (15*sizeof(float)) - but if you switch to a variable length array it wont even be that... You'll need to track the set length separately. Or use a std::vector<int>, or better yet - why reinvent the wheel and use std::set<int>?
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
#include<iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX=10;
class Order{
int number;
char** ord;
int capacity;
int top;
public:
Order();
Order(Order const&);
Order (int);
~Order();
bool full() const { return top==capacity;}
bool empty()const { return top<=0; }
Order& operator=(Order const&);
void addItem1(const char*);
void cancel();
void Resize();
friend ostream& operator<<(ostream& os,Order const& q);
};
Order::Order(){
number=0;
ord=NULL;
capacity=MAX;
top=0;
}
Order::Order(Order const& w):number(w.number),ord(NULL),
top(w.top),capacity(w.capacity)
{
ord = new char*[top];
for(int i=0;i<top;i++){
int k=strlen(w.ord[i])+1;
ord[i]=new char[k];
strncpy(ord[i],w.ord[i],k);
ord[i][k-1]='\0';
}
}
Order::Order(int x):ord(NULL),top(0),capacity(MAX){
number=x;
}
Order& Order::operator=(Order const& w){
if(this!=&w){
cancel();
ord = new char*[top];
for(int i=0;i<w.top;i++){
int k=strlen(w.ord[i])+1;
ord[i]=new char[k];
strncpy(ord[i],w.ord[i],k);
ord[i][k-1]='\0';
}
number=w.number;
top=w.top;
capacity=w.capacity;
return *this;
}
}
void Order::Resize(){
size_t Newcapacity=capacity*3/2+1;
char** tmp=new char*[Newcapacity];
for(int i=0;i<capacity;i++){
size_t s=strlen(ord[i])+1;
tmp[i]=new char[s];
strncpy(tmp[i],ord[i],s);
tmp[i][s-1]='\0';
}
for(int i=0;i<capacity;i++)
delete[]ord[i];
delete[] ord;
capacity=Newcapacity;
ord=tmp;
}
void Order::addItem1(const char* disc){
//if(full())
// Resize();
size_t p=strlen(disc)+1;
ord[top]=new char[p];
strncpy(ord[top],disc,p);
ord[top][p-1]='\0';
top++;
}
void Order::cancel(){
if(!empty()){
for(int i=0;i<capacity;i++)
delete[] ord[i];
delete[]ord;
capacity=MAX;
top=0;
ord=NULL;
}
}
Order::~Order(){
cancel();
number=0;
}
ostream& operator<<(ostream& os,Order const& t){
os<<t.number<<endl;
for(int i=0;i<t.top;i++){
os<<i<<". "<<t.ord[i]<<endl;
}
return os;
}
int main(){
int s1=257;
int s2=245;
int s3=244;
char S1[20]="Pile s oriz";
char S2[20]="Krem karamel";
char S3[20]="Salata";
Order p(s1);
p.addItem1(S1);
//p.addItem(S3);
//Order q(p);
//q.addItem(S2);
cout<<"First: "<<p<<endl;
//cout<<"Second: "<<q<<endl;
return 0;
}
Can s help me i dont know where is the error ?
I use Code::Blocks 10.05 if this matter.
0 errors, 0 warnings
Checking for existence: C:\Users\user1\Downloads\Нова папка\wtfff.exe
Executing: C:\Program Files (x86)\CodeBlocks/cb_console_runner.exe "C:\Users\user1\Downloads\Нова папка\wtfff.exe" (in C:\Users\user1\Downloads\Нова папка)
Process terminated with status -1073741510 (0 minutes, 8 seconds)
You use constructor
Order::Order( int x ) :ord( NULL ), top( 0 ), capacity( MAX )
after that ord = 0
Error of access in function:
void Order::addItem1( const char* disc )
there you try to ord[top] in
ord[top] = new char[p];
but ord = 0
I've searched all over stackoverflow but just can't seem to find what i'm looking for, so here goes..
I have 2 custom classes one being used in the second and when i'm trying to sort the second class.. which is essentially a vector of the first class it throws the error : - message 0x010c3e18 "vector iterators incompatible" const wchar_t *at vc\include\vector line 238 .. here is my code :
#include <iostream>
#include <conio.h>
#include <cmath>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
class cityPhone {
private:
string cityName;
string cityCode;
public:
void setCode(string code){
cityCode=code;
}
void setName(string name){
cityName=name;
}
cityPhone(){
cityName="Varna";
cityCode="0888123123";
}
cityPhone(string name, string code){
cityName=name;
cityCode=code;
}
string getCity(){
return cityName;
}
string getCode(){
return cityCode;
}
};
//struct { //ive used these 2 also and still it doesnt work
// bool operator()(cityPhone a, cityPhone b)
// {
// if (a.getCity().compare(b.getCity())>0)return true;
// return false;
// }
// } cmpCity;
// struct {
// bool operator()(cityPhone a, cityPhone b)
// {
// if (a.getCode().compare(b.getCode())>0)return true;
// return false;
// }
// } cmpCode;
bool cmpCity(cityPhone a, cityPhone b) // i'm using these 2 in the sorting method
{
if (a.getCity().compare(b.getCity())>0)return true;
return false;
}
bool cmpCode(cityPhone a, cityPhone b)
{
if (a.getCode().compare(b.getCode())>0)return true;
return false;
}
class phoneDirectory {
private :
vector<cityPhone> data;
public:
phoneDirectory (string path){
read(path);
}
phoneDirectory (){
data=vector<cityPhone>();
}
void read(string path){
cout<<endl;
try {
string line;
ifstream myfile (path);
cityPhone bla = cityPhone();
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
try{
bla = cityPhone(line.substr(0,line.find_first_of(" ")),line.substr(line.find_first_of(" ")+1));
data.push_back(bla);
}
catch(exception){ }
}
myfile.close();
}
else cout << "Unable to open file";
} catch (exception) {}
}
void addCityPhone(string city,string phone){
try{
data.push_back(cityPhone(city,phone));
}
catch(exception){
cout<<"Error adding item "<<endl;
}
}
void delCityPhone(int index){
try{
vector<cityPhone>::iterator p=data.begin();
p+=index;
data.erase(p);
}
catch(exception){
cout<<"Error deleting item with index "+index<<endl;
}
}
cityPhone getCityPhone(unsigned index){
try{
vector<cityPhone>::iterator p=data.begin();
p+=index;
return *p;
}
catch(exception){
cout<<"Error deleting item with index "+index<<endl;
return cityPhone();
}
}
vector<cityPhone> getData(){
return data;
}
void phoneChange(string city, string newPhone){
try{
int i=0;
vector<cityPhone>::iterator p=data.begin();
for(p=data.begin();p<data.end();p++,i++){
if (getCityPhone(i).getCity().compare(city)==0){
string oldPhone = getCityPhone(i).getCode();
getCityPhone(i).setCode(newPhone);
cout<<"Phone of city "+city + " was changed from "+oldPhone + " to " + newPhone<<endl;
return;
}
cout<<"No such city exists!\n";
}
}
catch(exception){
cout<<"Error changing phone"<<endl;
}
}
friend istream& operator>>(ostream& out,phoneDirectory a);
friend ostream& operator<<(ostream& out,phoneDirectory a);
};
istream& operator>>(istream& in,phoneDirectory& a){
string city,phone;
in >> city >> phone;
a.addCityPhone(city,phone);
return in;
}
ostream& operator<<(ostream &out, cityPhone a){
return out << a.getCity() <<" " << a.getCode() <<endl;
}
void sortByCity(phoneDirectory a){//with these two i try to sort
vector<cityPhone>::iterator p=a.getData().begin();
vector<cityPhone>::iterator q=a.getData().end();
std::sort(p,a.getData().end(),cmpCity);
}
void sortByCode(phoneDirectory a){
vector<cityPhone>::iterator p=a.getData().begin();
vector<cityPhone>::iterator q=a.getData().end();
std::sort(p,q,cmpCode);//i've tried with std::sort(a.getData().begin(),a.getData().end(),cmpCode) still no effect
}
//bool wayToSortCity (cityPhone a, cityPhone b){ //i've tryed also with these , still no effect
//if (a.getCity().compare(b.getCity())>0)return true;
//return false;
//}
// bool wayToSortCode (cityPhone a, cityPhone b){
//if (a.getCode().compare(b.getCode())>0)return true;
//return false;
//}
int main()
{
phoneDirectory test("C:\\t.txt");
sortByCity(test);//here it crashes
for(unsigned i=0;i<test.getData().size();i++)
cout<<test.getCityPhone(i);
cin>>test;
//test.sortBy(1);
system("pause");
return 0;
}
The problem is that phoneDirectory::getData returns a copy of the data member, so each iterator "belongs to" a different vector.
You need it to return the actual member, not a copy of it.
const vector<cityPhone>& getData() const
{
return data;
}
You have
void sortByCity(phoneDirectory a){//with these two i try to sort
vector<cityPhone>::iterator p=a.getData().begin();
vector<cityPhone>::iterator q=a.getData().end();
std::sort(p,a.getData().end(),cmpCity);
}
Problems with that function:
a.getData() returns a copy of the private data by value. Hence, p and q are iterators on different vectors. Comparing them leads to undefined behavior. You are not comparing p with q but you are comparing p with getData().end(), which is essentially the same thing.
Since the return value is a copy of the member data of a, these are temporary objects. The objects get destructed after the execution of the lines. p and q are the equivalent of dangling pointers.
The argument to the function is an object. After the above errors are fixed, you'll end of sorting a copy of the argument used to call the function. In the calling function, you still won't notice any difference.
The function sortByCode suffers from the same errors.
How to fix the problems
Change the argument type of the function to a reference.
void sortByCity(phoneDirectory& a){
With that change, you will notice any changes to the object in the calling function.
Change the return value of phoneDirectory::getData() to a reference.
vector<cityPhone>& getData(){
return data;
}
That will not only fix all the errors but it will also sort the contents a and not a copy of the contents of a.
Here's what I came up with, I just want the program to pop the first 2 values in the stack, calculate them and push the back into the stack...I've already created the functions required but there seem to be a problem with the function that adds the two numbers.
#include <iostream>
using namespace std;
int Maxlenght=5;
class stackhouse{
private:
int *CreateArray;
int top;
public:
stackhouse();
bool IsEmpty();
bool IsFull();
void constructor();
void Push(int);
void Pop(int);
void Sum();
void Sub();
};
stackhouse::stackhouse(){
CreateArray= new int[Maxlenght];
top=-1;
}
bool stackhouse::IsEmpty()
{
if (top==-1) return 1;
else return 0;
}
bool stackhouse::IsFull(){
if (top==Maxlenght-1) return 1;
else return 0;
}
void stackhouse::Push(int number){
top++;
CreateArray[top]=number;
}
void stackhouse::Pop (int number){
number=CreateArray[top];
top--;
}
void stackhouse::Sum(){
int number=7,sum=5;
Pop(sum);
Pop(number);
sum+=number;
Push(sum);
cout<<sum;
}
void main(){
int number;
stackhouse stack1;
stackhouse();
cout<<"Please fill the stack...";
stack1.Push(5);
stack1.Push(2);
cout<<"The sum is...";
stack1.Sum();
}
The Pop function needs to either return number or pass number by reference; otherwise, the assignment to number has no effect.
void stackhouse::Pop(int& number) { // <-- add the &
number = CreateArray[top];
top--;
}
Or
int stackhouse::Pop() {
int number = CreateArray[top];
top--;
return number;
}
(Note that the second way requires you to write sum = Pop() instead of Pop(sum).)
Passing a parameter by value to the pop() method is pointless. It needs to return a value.
This is my Code
#ifndef INTLIST_H_INCLUDED
#define INTLIST_H_INCLUDED
#include <iostream>
using namespace std;
class intList
{
int upper_bound;
int arr[0];
public:
intList(){ arr[0] = 0; upper_bound = 0; }
void append(int x);
void sort();
friend ostream & operator << (ostream &, intList&);
inline int len(){ return upper_bound; }
inline int &operator [](int x){ return arr[x]; }
private:
void increment(int *a, int &l);
void swap(int &a, int &b);
};
void intList::swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
void intList::increment(int *a, int &b)
{
b++;
a[b] = 0;
}
void intList::append(int num)
{
arr[upper_bound] = num;
increment(arr, upper_bound);
}
void intList::sort()
{
for(int i = 0; i < upper_bound; i++)
{
int minLoc = i;
for(int j = i+1; j<upper_bound; j++)
{
if(arr[j] < arr[minLoc])
minLoc = j;
}
if(minLoc != i)
swap(arr[i], arr[minLoc]);
}
}
ostream& operator << (ostream & dout, intList &a)
{
dout << "[ ";
for(int i = 0; i<a.upper_bound-1; i++)
dout << a.arr[i] << ", ";
dout << a.arr[a.upper_bound-1] << " ]";
return dout;
}
#endif // INTLIST_H_INCLUDED
The Code does its work perfectly fine. But at the end the Program Crashes. Giving some error like
process returned -1073741819 (0xC0000005) execution time : some seconds.
Just didn't get where am I going wrong.
This looks bad:
int arr[0];
First, C++ doesn't allow zero-sized fixed size arrays. Second, your code certainly needs more than a zero sized array.
Whatever use you make of this code is undefined behaviour (UB). UB includes code seemingly "working perfectly fine".
Your code has several problems.
For example, you have a fixed array of 0 size. If you want a dynamically growable array, you can use std::vector: you can add new items at the end of the vector (dynamically resizing it) using push_back() method:
#include <vector>
// Start with an empty vector
std::vector<int> v;
// Add some items to it
v.push_back(10);
v.push_back(20);
....
Note also that in header files it's not good to insert a using namespace std;. In this way you pollute the global namespace with STL classes, which is bad. Just use std:: prefix in header files.
Moreover, if you want to print the class content to an output stream, you may want to take the class as a const reference, since instances of the class are input parameters (you observe them and print their content to the stream):
std::ostream& operator<<(std::ostream& os, const IntList& a)
{
....
}