Why am I getting a segmentation fault? What am I doing wrong? - c++

Problem: A program to count the number of times a number repeats in an array using recursion.
What I've done: I've tried every way I know, I've gone with an output array for storing indices of the number, and just ++ to another number on finding a match to current number. Nothing seems to work, it's one error or another (I'm a noob). I tried looking for solutions online, found solutions on 3-4 websites but had no clue what was going on.
Here's the code:
#include <iostream>
using namespace std;
int ind(int a[], int size, int x){
int j;
if(size == 0){
return 0;}
else if (a[0]==x){
j++;
return j;
}
reind(a++,size—,x);
}
int main(){
int a[5] = {1,2,3,3,5};
ind(a, 5, 3);
}
Edit: That "reind" was a typo, I still get segmentation fault with "ind". Sorry for that.

There are quite a number of mistakes in this code:
j is uninitialized, and even if it weren’t, you are not using the value of j correctly.
There is a missing return on the recursive call to ind() (is that what the re was supposed to be?).
You are passing the original values of a and size to the recursive ind(), causing an endless loop. You are using the post-increment and post-decrement operators, which return the original values, not the new values. You would need to use the pre-increment and pre-decrement operators instead. Which is a bit overkill in this situation, as you don’t use the variables anymore after they are adjusted. So simple addition and subtraction operators can be used instead.
main() is ignoring the return value of ind().
Try this instead:
#include <iostream>
using namespace std;
int ind(int a[], int size, int x){
int j = 0;
if (size == 0){
return 0;
}
if (a[0] == x){
++j;
}
return j + ind(a+1, size-1, x);
}
int main(){
int a[5] = {1, 2, 3, 3, 5};
cout << ind(a, 5, 3);
}
Live Demo
That being said, j and the 2nd if can be eliminated completely:
int ind(int a[], int size, int x){
if (size == 0){
return 0;
}
return (a[0] == x ? 1 : 0) + ind(a+1, size-1, x);
}
Or:
int ind(int a[], int size, int x){
if (size == 0){
return 0;
}
return int(a[0] == x) + ind(a+1, size-1, x);
}

Related

program To find the repetition of a number

here's a problem that I can't figure it out
The program should count the repetition of a number but when I run the program it seems that the function calls itself once not until the array ends as it's required
any help?
This is the code please have a look :)
#include <stdio.h>
int count(int arr[],int counter,int size, int num,int i) {
if (size != 0) {
while (i<10) {
if (arr[size - i] == num) {
count(arr, size, counter++, num, i++);
}
else
return counter;
}
}
int main() {
int result,n,i=1;
int arr[] = {1,2,2,3,7,2,5,3,8,7};
scanf("%d", &n);
result=count(arr, 0,10,n,i);
printf("%d", result);
return 0;
}
This might be help you:
#include <stdio.h>
int count(int arr[],int counter,int size, int num,int i) {
if (size != 0) {
for (;i<size;i++) {
if (arr[i] == num) {
counter++;
}
}
}
return counter;
}
int main() {
int result,n,i=0,countt=0;
int arr[] = {1,2,2,3,7,2,5,3,8,7};
scanf("%d", &n);
result=count(arr, countt,10,n,i);
printf("%d", result);
return 0;
}
If you are using recursion to iterate over the input array, you should not loop over the same array in the recursive function.
Couple of problem in your code:
Function is not returning anything when this if condition results in false:
if (size != 0) {
Compiler must be giving warning on this regards.
Here, you are not ignoring the return value of count():
count(arr, size, counter++, num, i++);
Your recursive function count() is supposed to return the frequency of num. So, you should receive the value returned by count() as it accumulate the frequency of num during recursive call.
This can be easily solved using recursion. You can do:
#include <stdio.h>
int count (int *arr, int counter, int size, int num) {
// terminating condition
if (size <= 0) {
return counter;
}
// check the current processing number
if (*arr == num) {
counter++;
}
// recursive call to process next number
return count (arr + 1, counter, size - 1, num);
}
int main() {
int arr[] = {1,2,2,3,7,2,5,3,8,7};
int result, n;
printf ("Enter a number:\n");
scanf ("%d", &n);
result = count(arr, 0, sizeof (arr)/sizeof (arr[0]), n);
printf ("Frequency of %d is %d\n", n, result);
return 0;
}
Additional:
Do not hardcode the size of an array. You can use sizeof operator to get an array size at compile time, like this:
sizeof (arr)/sizeof (arr[0])
Make yourself aware of tail recursion, if you are not:
A function call is said to be tail recursive if there is nothing to do after the function returns except return its value. A tail recursive function can be easily transformed into an iterative one and hence compilers can also optimize the code for such functions by eliminating the recursion, that means, tail recursive calls run in constant stack space, i.e. they don't need to create new stack frames when they recursively call themselves. Check following for better idea:
How exactly does tail recursion work?

print out even numbers between two integers

I need to create a function to print out even numbers between two integers
#include <iostream>
using namespace std;
int evens_between(int m, int n)
{
for(int i = m; i<= n; i++)
{
if(i % 2 == 0)
cout<<i<<" ";
}
}
int main()
{
int m;
int n;
cin>>m>>n;
cout<<evens_between(m,n)<<endl;
return 0;
}
I'm getting error messages not sure if this is right though. Would appreciate some help understanding my error a little better
You're trying to print the function's result here:
cout<<evens_between(m,n)<<endl;
But that's wrong. Just call the function:
evens_between(m,n);
However, the error is because you're making the function return an int. At least you tell it to do so in its signature, it's not actually returning any value. Change it to void instead:
void evens_between(int m, int n)

Finding number of occurence of a given number in an array

I'm testing a recursive function that returns the number of occurrence of a given number in an array. I get an unexpected result when I run the code.
#include <iostream.h>
int Occurence(int A[], int size, int n)
{
static int occur=0;
if(size == 0)
{
int occur2 = (int) occur;
return occur2;
}
else
{
if ( n == A[size-1])
occur++;
Occurence(A, size-1, n);
}
}
int main()
{
int A[] = {1,3,2,5,1,2, 3, 7,7, 8,8, 4, 6, 9,9, 0};
int size = sizeof(A)/sizeof(A[0]);
int n;
cout<< "Enter Number to Find : ";
cin >>n;
cout<<endl;
cout<<"Number of Occurence of "<< n << " is :"<< Occurence(A, size, n)<<endl;
return 0;
}
You are missing a return at the end of your function. If size is not 0 then the behaviour of your function is undefined. Adding the return should make it work:
int Occurence(int A[], int size, int n)
{
static int occur=0;
if(size == 0)
{
int occur2 = (int) occur;
return occur2;
}
else
{
if ( n == A[size-1])
occur++;
return Occurence(A, size-1, n);
}
}
Recursion is a very strange way to implement this problem so I assume this is some toy example to demonstrate how recursion works. Even if this is the case you really shouldn't be using a static variable in your implementation. Just make each call return the current sum instead:
int Occurence(int A[], int size, int n)
{
if(size == 0)
{
return 0;
}
else
{
return (n == A[size-1] ? 1 : 0) + Occurence(A, size-1, n);
}
}
This version will return the correct result when called multiple times whereas your original would add to the previous count each time.
In real code simply do:
#include <algorithm>
int Occurence(int A[], int size, int n)
{
return std::count(A, A+size, n);
}
There are some compilation problems in your code. First of all, in C++, the standard library files usually don't have an extension in the filename. So, including <iostream.h> is wrong. You should include <iostream>.
Other problem with your code is that you are using cout and cin without specifying their namespaces. So, instead of using cout and cin directly, use std::cout and std::cin or declare use namespace std after your includes.
EDIT: as Thomas Matthews pointed out, prefer using std::cout and std::cin over using namespace std.

Variables being affected by 'bad' instructions

Below is my code, for solving problem 7 of PE ("find the 10001th prime"):
#include <iostream>
using namespace std;
bool isPrime(int n, int primes[], int l){
int i=0;
for (int i=0; i < l; i++){
if (primes[i] != 0 && n%primes[i] == 0){
return false;
}
}
return true;
}
int main()
{
int k=3;
int primes[10001] = {0};
primes[0]=2;
const int l=sizeof(primes)/sizeof(primes[0]);
int N=0;
while (N < l){
if(isPrime(k, primes, l)==true){
primes[++N]=k;
}
k+=2;
}
cout << primes[l-1] << endl;
return 0;
}
This code solves the problem, but there is a mistake in it: on the final iteration of the while loop, the instruction is to set primes[10001]=k;, which attempts to change a value of an element of an array that doesn't exist. If I don't declare it to be constant, and (as a means of troubleshooting) replace l by 10001 in the while loop, the value of l becomes equal to the 10002th prime at the end of the loop.
Here is the main function part of this happening:
int main()
{
int k=3;
int primes[10001] = {0};
primes[0]=2;
int l=sizeof(primes)/sizeof(primes[0]);
int N=0;
while (N < l){
if(isPrime(k, primes, 10001)==true){
primes[++N]=k;
}
k+=2;
}
cout << l << endl;
return 0;
}
My question is, why does this happen? I do know that a simple fix is to stop the loop at l-1 (or better, initialize with N=1 instead and increment N after), but I'm more interested in how this code can affect a variable that isn't being explicitly (directly?) involved in the bad part of the code.
Thank you!
The [] Operator does no bounds checking. some_array[102], will simple go 102 * sizeof(type) if thats outside your array, thats outside your array. C++ won't care.
These are some of the nastiest bugs that can generated if you are lucky you program will crash, sometimes you can just end up changing somebody else's variable.
Which is why I harp on at work about using std::array and std::vector alot because they come with .at(i) functions which have bounds checking.

Floating point exception

#include <cstdio>
#include <ctime>
int populate_primes(int array[])
{
const int max = 1000000;
char numbers[max+1];
int count=1;
array[0]=2;
for(int i=max;i>0;i-=2)numbers[i]=0;
for(int i=max-1;i>0;i-=2)numbers[i]=1;
int i;
for(i=3;i*i<=max;i+=2){
if(numbers[i]){
for(int j=i*i;j<max+1;j+=i)numbers[j]=0; array[count++]=i;
}
}
int limit = max/2;
for(;i<limit;i++) if(numbers[i])array[count++]=i;
return count;
}
int factorize(int number,int array[])
{
int i=0,factor=1;
while(number>0){
if(number%array[i]==0){
factor++;
while(number%array[i]==0)number/=array[i];
}
i++;
}
printf("%d\n",factor);
return factor;
}
int main()
{
int primes[42000];
const int max = 1000000;
int factors[max+1];
clock_t start = clock();
int size = populate_primes(primes);
factorize(1000,primes);
printf("Execution time:\t%lf\n",(double)(clock()-start)/CLOCKS_PER_SEC);
return 0;
}
I am trying to find the no. of factors using simple algo. The populate primes part is running okay , but the factorize part does not execute and gives the floating point exception error.
Please see the code and tell my mistake.
In your factorize method you access array[0], because the initial value of i is 0.
This array is the primes array which is populated by populate_primes. But populates prime doesn't write to primes[0], since the initial value of count is 1.
Thus the first element is not initialized and you probably get a div by 0 error.
You need to pass the size which you got from populate to factorize.
factorize(int number, int array[], int size);
problem is your array[] is not fully loaded, it is loaded only till size variable. So you may want to check for that.
Also the logic inside factorize is wrong. You need to check (number > 1) rather than (number >0).
Try with the function below to see some problems:
#define MAX_PRIMES 42000
int factorize(int number,int array[])
{
int i=0,factor=1;
for (i=0; number>0 && i< MAX_PRIMES; i++){
if (array[i] == 0 || array[i] == 1) {
printf("Error: array[%d] = %d\n", i, array[i]);
} else {
if(number%array[i]==0){
factor++;
while(number%array[i]==0 && number>0) {
printf("%d %d\n", number, array[i]);
number/=array[i];
}
}
}
}
printf("%d\n",factor);
return factor;
}