Segmentation fault in sorting algorithm - c++

so when I run the following code in Xcode, it works, but gives segmentation fault when I run it in terminal and I'm not sure why.
void Word::arrangeWords(char **&words, int*& pages, int size)
{
char *lowest;
int track;
{
for (int i=0;i<size;i++)
{
lowest=new char[30];
strcpy(lowest, words[i]);;
for(int j=i+1;j<size;j++)
{
int compResult=strcmp(lowest, words[j]);
if (compResult>0)
{
strcpy(lowest, words[j]);
track=j;
}
}
std::swap(words[track],words[i]);
std::swap(pages[track],pages[i]);
delete [] lowest;
}
}
}
Thanks in advance

I can't figure out what's causing the segmentation fault but there is a bug in your code. You are not resetting the value of track after the calls to std::swap. I suggest the following changes to the function.
void Word::arrangeWords(char **&words, int*& pages, int size)
{
for (int i=0;i<size;i++)
{
int track = i;
char lowest[30]; // If you know the size of the array to be 30,
// just create an array. Why use new char[30]?
strcpy(lowest, words[i]);;
for(int j=i+1;j<size;j++)
{
int compResult=strcmp(lowest, words[j]);
if (compResult>0)
{
strcpy(lowest, words[j]);
track=j;
}
}
if ( track > i )
{
std::swap(words[track],words[i]);
std::swap(pages[track],pages[i]);
}
}
}

Related

Unable to access vector value by index

#include<iostream>
#include<vector>
using namespace std;
class Stack
{
public:
int top;
vector<int> v;
Stack(int size)
{
top=0;
cout<<"Enter the values"<<endl;
for(int i=0; i<size; i++)
{
int val;
cin>>val;
v.push_back(val);
top++;
}
}
void push(int val)
{
v.push_back(val);
top++;
}
int pop()
{
int x=v[top];
top--;
return x;
}
void disp()
{
for(int j=top; j<=0; j--)
cout<<v[j]<<' ';
}
};
int main()
{
Stack s(3);
int k=s.pop();
cout<<k;
return 0;
}
I am trying to learn the basics of OOP.
Here, my Stack constructor and push function are working fine, but there is a problem with the pop and disp functions.
I'm assuming that I am using an incorrect syntax to access the elements of a vector(maybe?). Can anyone tell me where I am going wrong?
Also, the value of k always comes out to be 0.
You can use the vector functions
int k = s.back();
s.pop_back();
cout << k;
more informationhttp://www.cplusplus.com/reference/vector/vector/back/
You have a off-by-one index error.
The way you have implemented your class, when there are N items in the stack, the value of top is N.
Hence, top is not a valid index to access the elements of v. You can use:
int pop()
{
int x=v[top-1];
top--;
return x;
}
or
int pop()
{
top--;
int x=v[top];
return x;
}
As some of the other answers say, you can use the built-in vector functions to do these things (see pop_back and back.
However, if you want to define your own, I would use the vector.at(index) function. Addressing the values with the index as you have works, but it doesn't do any bounds checking at() does. Which would solve your problem above where your index isn't correct for the zero-based indexing of a vector.

How to swap elements in 2d array c++

I'm trying to make a 15 puzzle game by swapping an element with the position of a blank element. I've made this code, but it only swaps when the tile is to the right or below for some reason.
void moveTile(int gameBoard[][SIZE], int nextMove, int &blanki, int &blankj)
{
int temp=nextMove;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(gameBoard[i][j]==nextMove)
{
gameBoard[i][j]=gameBoard[blanki][blankj];
gameBoard[blanki][blankj]=temp;
blanki=i;
blankj=j;
}
}
}
}
Walk thru it in a debugger. You'll see that after a swap is made, you keep going and searching. In the case where the tile is above or left, you'll swap a second time.
You need to stop searching once you've made a swap.
I have updated it to include a stop, now the code does not iterate.
void moveTile(int gameBoard[][SIZE], int nextMove, int &blanki, int &blankj)
{ bool stop=false;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
while(!stop)
{if(gameBoard[i][j]==nextMove)
{
int temp=gameBoard[i][j];
gameBoard[i][j]=gameBoard[blanki][blankj];
gameBoard[blanki][blankj]=temp;
blanki=i;
blankj=j;
stop=true;
}
}
}
}
}

Trying C++ on Xcode on Mac- ERROR-exc_bad_access (code=1 address=0x100500000)

I have been trying to write a program where I have to read a binary file which has around 30 million long values and we have to find out the modes I have successfully done it using a smaller number of values but when I try with the file it always gives me the error- exc_bad_access (code=1 address=0x100500000), I am trying it in Xcode on my MAC and implementing in C++. The code is as below, can anyone help me out?
#include <iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
void mode(long data[], long size, long &num_modes, long modeNums[], long &maxFrequency);
int main()
{
long *data,*modeNums, size;
ifstream binaryin("TestData.bin", ios::binary);
binaryin.read(reinterpret_cast<char *>(&size), 4);
data = new(nothrow)long[size];
if(!data)
{ cout<<"Memory allocation error for data array, program will terminate\n";
system("pause");
exit(0); }
binaryin.read(reinterpret_cast<char *>(data),size*sizeof(long));
//cout<<"SIZE "<<size<<endl;
long num_modes;long maxFrequency;
modeNums=new(nothrow)long[size];
size=3000000;
mode(data,size,num_modes,modeNums,maxFrequency);
/* for(int i=0;i<20;i++)
cout<<"data[i]"<<data[i]<<endl;*/
// cout<<"maxFrequency= "<<maxFrequency;
// cout<<"\nnum_modes= "<<num_modes<<endl;
// for(int i=0;i<num_modes;i++)
// cout<<"modeNums[]= "<<modeNums[i]<<endl;
}
void mode(long data[], long size, long &num_modes, long modeNums[], long &maxFrequency)
{
// size=300000;
// cout<<"SIZE "<<size<<endl;
int cnt=0,val=0;// long *arr,*arr1;
vector<long> arr;
vector<long> arr1;
//arr=new(nothrow)long[size/2];
//arr1=new(nothrow)long[size/2];
// cout<<"INSIDE THE FUNCTION\n";
//cout<<"SIZE "<<size<<endl;
long k;
//cout<<"SIZE "<<size<<endl;
cout<<"\nstarting for loop\n";
for(int i=0;i<size;i++)
{ cout<<"Inside for loop\n";
cnt=0; k=(size-1);
long num=data[i];
int flag=0;
int temp=val;
while(temp!=0)
{ cout<<"inside while loop\n";
if(arr[temp]==num)
{ flag=1;}
temp--;
}
if(flag==0){
int count=0;
for(int j=0;j<(size/2);j++)
{// cout<<"Inside for which is inside while\n";
cout<<"data[j] "<<data[j]<<" "<<"data[k] "<<data[k]<<endl;
cout<<"COUNT "<<count++<<endl;
if(num==data[j] && num==data[k])
{ cnt+=2; }
else if(num==data[j]||num==data[k])
{ cnt++; }
k--;
}
arr.push_back(num);arr1.push_back(cnt);
val++;
}
else
flag=2;
}
cout<<"\nend of for loop\n";
// for(int i=0;i<val;i++)
// cout<<"NUM "<<arr[val]<<"Mode "<<arr1[val]<<endl;
maxFrequency=0;
for(int i=0;i<val;i++)
{
if(arr1[i]>maxFrequency)
maxFrequency=arr1[i];
}
num_modes=0; int value=0;
for(int i=0;i<val;i++)
{
if(arr1[i]==maxFrequency)
{ num_modes++;
modeNums[value]=arr[i];
value++; }
}
/* int value=0;
for(int i=0;i<val;i++)
{
if(maxFrequency==arr1[i])
{ modeNums[value]=arr[i];
value++;}
} */
// for(int i=0;i<val;i++)
// cout<<"Value "<<arr[i]<<" Mode "<<arr1[i]<<endl;
// cout<<"maxFrequency= "<<maxFrequency<<endl;
// cout<<"\nnum_modes= "<<num_modes<<endl;
cout<<"\nend of function\n";
}
enter image description here
This line:
size=3000000;
means that you allocate your arrays of a certain size (whatever you read from the file), then tell your mode function that those arrays are actually 3000000 longs in size. This could lead to a buffer overrun.
I can't see any reason for this line to be in there.
Also if you use new(nothrow) you should check the return value.

Prime numbers in an dynamic array

I've a program which inserts all prime numbers up to a specific number in an array.
The calculation is correct. My problems are the function parameters and the transfer of my dynamic array to the function. My function doesn't modify my array.
Please take a look at the code:
#include <iostream>
using namespace std;
int primeinlesen(int *i);
int primarrayspeicherung (int *primarray,int *bis);
int main()
{
int reload=1;
while(reload==1)
{
int bis=0,*primarray,valcounter;
primeinlesen(&bis);
valcounter=primarrayspeicherung(primarray,&bis);
for(int i=0;i<valcounter;i++)
{
cout<<i<<". Primzahl: "<<primarray[i]<<"\n";
}
delete [] primarray;
cout<<"Anzahl Primzahlen: "<<valcounter<<endl;
cout<<"Erneute Berechnung?(Ja(1) oder Nein(0))";
cin>>reload;
}
return 0;
}
int primeinlesen(int *i)
{
cout<<"Bis zu welchem Wert moechten SiePrimzahlen ausgegeben,haben(max.500)";
cin>>*i;
if(*i>500)
{
cout<<"Wert zu hoch...";
}
return 0;
}
int primarrayspeicherung (int *primarray,int *bis)
{
int x,y,counter,e,valcounter=0,xcounter=0,xvalcounter=0,xx,xy,xe;
for(x=2;x<*bis;x++)
{
counter=0;
for(y=2;y<x;y++)
{
e=x%y;
if(e==0)
{
counter++;
}
}
if(counter==0)
{
valcounter++;
}
}
//ZWEITER DURCHGANG
primarray=new int[valcounter];
for(xx=2;xx<*bis;xx++)
{
xcounter=0;
for(xy=2;xy<xx;xy++)
{
xe=xx%xy;
if(xe==0)
{
xcounter++;
}
}
if(xcounter==0)
{
primarray[xvalcounter]=xx;
xvalcounter++;
}
}
return valcounter;
}
Best regards
In this function:
int primarrayspeicherung (int *primarray,int *bis)
primarray is a local variable. Everything you're doing to it (e.g. allocating, assigning) only affects the local primarray, not the one you pass in. If you want to modify both, you need to pass in a reference:
int primarrayspeicherung (int*& primarray,int *bis)

NFA simulator error C++

I have one big problem with my NFA simulator.
When I run the code sometimes everything goes nice, but sometimes I get this
Process terminated with status -1073741819(0xC0000005)
What do I miss out and what to do to get this work fine?
This is the code:
#include <iostream>
#include<fstream>
#include<map>
using namespace std;
ifstream fin("fisier.txt");
class NFA {
int initiala,finale,stari,tran,cuvinte;
int *f;
multimap <pair <int,int>,char>t;
public:
void stari_finale();
void tranzitii();
void rezolvare();
};
void NFA::stari_finale()
{
fin>>finale;
f=new int[finale];
for(int i=1;i<=finale;i++)
fin>>f[i];
}
void NFA::tranzitii()
{
fin>>tran;
for(int i=1;i<=tran;i++)
{
int x,y;
char c2;
fin>>x>>y>>c2;
t.insert(make_pair(make_pair(x,y),c2));
}
}
void NFA::rezolvare()
{
fin>>stari>>initiala;
fin>>cuvinte;
for(int i=1;i<=cuvinte;i++)
{
int l;
fin>>l;
char *cuv=new char[l+1];
fin.get();
fin.getline(cuv,l+1);
int *c=new int[stari],nr=1;
c[1]=initiala;
for(int j=0;j<l;j++)
{
int *c1=new int[stari];
int n=0;
for(int k=1;k<=nr;k++)
for(int z=0;z<=stari;z++)
if(t.find(make_pair(c[k],z))!=t.end())
if(t.find(make_pair(c[k],z))->second==cuv[j])
n++,c1[n]=z;
for(int k=1;k<=n;k++)
c[k]=c1[k];
nr=n;
delete c1;
}
for(int j=1;j<=nr;j++)
{for(int k=1;k<=finale;k++)
if(c[j]==f[k])
{
cout<<"Word "<<cuv<<" is accepted!\n";
nr=-1;
break;
}
if(nr==-1)
break;
}
if(nr!=-1)
cout<<"Word "<<cuv<<" isn't accepted!\n";
delete c;
delete cuv;
}
}
int main()
{
NFA test;
test.stari_finale();
test.tranzitii();
test.rezolvare();
return 0;
}
One major problem is you are not calling the right delete on your variables. If you call new you need to call delete. If you call new[] you need to use delete[]. Mixing new[] and delete calls will cause undefined behavior which is a symptom of what is happening.
Your calls to delete for c, c1 and cuv should all be delete [] variable_name
You are writing outside the array here:
void NFA::stari_finale()
{
fin>>finale;
f=new int[finale];
for(int i=1;i<=finale;i++)
fin>>f[i];
}
f has the size finale, but i will be equal to finale in the last iteration.
Use this instead:
void NFA::stari_finale()
{
fin>>finale;
f=new int[finale];
for(int i=0;i<finale;i++)
fin>>f[i];
}
or, if you really need to use the 1-based indexing:
void NFA::stari_finale()
{
fin>>finale;
f=new int[finale + 1];
for(int i=1;i<=finale;i++)
fin>>f[i];
}