Algorithm causes segmentation fault - c

I have built an algorithm that follows the following:
input n
print n
if n = 1 then STOP
if n is odd then n ←− 3n + 1
else n ←− n/2 GOTO 2
Whereby if n = 22 this should print out:
22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
Given an input n, it is possible to determine the number of numbers printed before and including the 1 is printed. For a given n this is called the cycle-length of n. In the example above, the cycle length of 22 is 16.
Therefore I have to determine the cycle-length between and including two integers i,j respectively.
#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 100
int test(int i, int j){
int* z[MAXSIZE];
int n = j-i;
int *p;
p = &j;
int o = 0;
while(&free){
int k = 0;
printf("\n%d -> %d ->> %d & %d", i, j, n, *p);
while(&free){
if (i == 1){
break;
} else if ((i % 2) != 0)
{
i = 3*i+1;
} else{
i = i/2;
}
k++;
}
(*z)[o] = k;
o++;
if (n == 1){
break;
}
n--;
i = *p-n;
}
size_t size = sizeof(z)/sizeof(z[0]);
int m = 0;
for (int i = 0; i < size; i++){
//printf("\n RESULTS: -- %d", (*z)[i]);
if (m < (*z)[i]){
m = (*z)[i];
} else {
continue;
}
}
return m;
}
int main(){
int i=900;
int j=1000;
int result;
result = test(i,j);
printf("\n RESULT: %d", result);
return 0;
}
However, this is producing a segmentation fault which it caused my pointer deficiency, however, I cannot locate it.
UPDATE:
Based on the comments, I believe the programme now runs as intended

"producing a segmentation fault " that is because (*z) is UB.
z is an uninitialized array of pointers.

Related

C program to find the trailing ZEROS at the end of a FACTORIAL of a given number

I have return the code to find a factorial and to display trailing zeros at the end of the factorial, but the output is wrong... could you please help me to find the mistake?
#include <stdio.h>
int main() {
int m = 1, i, N, count = 0;
scanf("%d", &N);
for (i = 1; i <= N; i++) {
m = m * i;
}
printf("%d", m);
while (m > 0) {
if ((m % 10) == 0) {
count = count + 1;
m = m / 10;
}
break;
}
printf("%d", count);
return 0;
}
Your code only works for very small values of N: up to 9. For slightly larger values, you would need to add an else keyword before the break statement and you would get a correct result for a few more cases.
For larger values, you must compute the power of 5 that divides the factorial. You can do this incrementally by summing the power of 5 that divide each individual number up to and including N.
#include <stdio.h>
int main() {
int N, count;
if (scanf("%d", &N) != 1)
return 1;
/* only consider factors that are multiples of 5 */
count = 0;
for (int i = 5; i <= N; i += 5) {
for (int j = i; j % 5 == 0; j /= 5)
count++;
}
printf("%d\n", count);
return 0;
}
An even simpler and faster solution is this: compute the number of multiples of 5 less or equal to N, add the number of multiples of 5*5, etc.
Here is the code:
#include <stdio.h>
int main() {
int N, count;
if (scanf("%d", &N) != 1)
return 1;
count = 0;
for (int i = N; (i /= 5) > 0;) {
count += i;
}
printf("%d\n", count);
return 0;
}
you have two problems
your collapse the two outputs so you see only one of them / you cannot see who is who, just add a separator between them
an else is missing when you count so you count to only up to 1 and the result is wrong from factorial 10
So the minimal changes produce :
int main()
{
int m=1,i,N,count=0;
scanf("%d",&N);
for(i=1;i<=N;i++)
{
m=m*i;
}
printf("%d\n",m); /* <<< added \n */
while(m>0)
{
if((m%10)==0)
{
count=count+1;
m=m/10;
}
else /* <<< added else */
break;
}
printf("%d\n",count); /* <<< added \n */
return 0;
}
after the changes :
pi#raspberrypi:/tmp $ ./a.out
5
120
1
pi#raspberrypi:/tmp $ ./a.out
10
3628800
2
Of course that supposes first you are able to compute the factorial without overflow
I also encourage you to check a value was read by scanf, checking it returns 1
#include <stdio.h>
int main()
{
int n,i,f=1,t,c=0;
printf("Enter number ");
scanf("%d",&n);
t=n;
for(i=1;t>=5;i++)
{
t=n/5;
c=c+t;
n=t;
}
printf("number of zeros are %d",c);
return 0;
}

for loop unexpectedly jumping down in value

Goldbach's conjecture states that every even integer over 4 is the sum of two primes, I am writing a program in C to find these pairs. To do this it first finds all the primes less than a user given number. I have a for loop to iterate from 4 to the user given number and find the pairs within the loop body. When that loop gets to about around 40, suddenly jumps back down by about 30 and then continues to iterate up (with user input 50 it jumped from 38 to 9, with input 60 it jumped from 42 to 7). I can't figure out why this is happening. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <unistd.h>
struct pair{
int a;
int b;
}pair_t;
int main(){
int N;
int numPrimes = 1;
int *primes = malloc(100*sizeof(int));
int isPrime = 1;
primes[0] = 2;
int timesRealloc = 0;
int availableSlots = 100;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
struct pair pairs[N/2 + 4];
int j = 0;
int i;
for (i = 3; i <= N; i+=2){
j = 0;
isPrime = 1;
while (primes[j] <= sqrt(i)) {
if (i%primes[j] == 0) {
isPrime = 0;
break;
}
j++;
}
if (isPrime == 1){
primes[numPrimes] = i;
numPrimes++;
}
if (availableSlots == numPrimes){
timesRealloc++;
availableSlots += 100;
primes = realloc(primes, availableSlots*sizeof(int));
}
}
printf("The largest prime I found was %d\n", primes[(numPrimes-1)]);
int k;
for (i=4; i<=N; i+=2){
printf("i is %d, N is %d\n", i, N);
if (i > N){ break; }
for (j=0; j<numPrimes; j++){
for (k=0; k<numPrimes; k++){
int sum = primes[j] + primes[k];
if(sum == i){
pairs[i].a = primes[j];
pairs[i].b = primes[k];
}
}
}
}
for (i=4; i<=N; i+=2){
printf("%d is the sum of %d and %d\n", i, pairs[i].a, pairs[i].b);
}
return 0;
}
You attempt to be space efficient by compressing the pairs array to just hold every other (even) number and start from 4 instead of zero. However, you miscalculate its size and then when you go to use it, you treat it like it hasn't been compressed and that there's a slot for every natural number.
The code suffers from having the prime array calculation in main() along with the other code, this is best separated out. And when it looks for pairs, it doesn't quit when it finds one, nor when it starts getting sums greater than the target. My rework below attempts to address all of these issues:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#define INITIAL_SLOTS (100)
struct pair {
int a;
int b;
} pair_t;
int compute_primes(int limit, unsigned **primes, int size) {
int numPrimes = 0;
(*primes)[numPrimes++] = 2;
for (int i = 3; i <= limit; i += 2) {
bool isPrime = true;
for (int j = 0; (*primes)[j] <= i / (*primes)[j]; j++) {
if (i % (*primes)[j] == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
(*primes)[numPrimes++] = i;
}
if (numPrimes == size) {
size *= 2;
*primes = realloc(*primes, size * sizeof(unsigned));
}
}
return numPrimes;
}
int main() {
int N;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
unsigned *primes = calloc(INITIAL_SLOTS, sizeof(unsigned));
int numPrimes = compute_primes(N, &primes, INITIAL_SLOTS);
printf("The largest prime I found was %d\n", primes[numPrimes - 1]);
struct pair pairs[(N - 4) / 2 + 1]; // compressed data structure
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
bool found = false;
for (int j = 0; ! found && j < numPrimes; j++) {
for (int k = 0; ! found && k < numPrimes; k++) {
int sum = primes[j] + primes[k];
if (sum == i) {
pairs[offset].a = primes[j];
pairs[offset].b = primes[k];
found = true;
} else if (sum > i) {
break;
}
}
}
}
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
printf("%d is the sum of %d and %d\n", i, pairs[offset].a, pairs[offset].b);
}
free(primes);
return 0;
}
OUTPUT
> ./a.out
Please enter the largest even number you want to find the Goldbach pair for:
10000
The largest prime I found was 9973
4 is the sum of 2 and 2
6 is the sum of 3 and 3
8 is the sum of 3 and 5
10 is the sum of 3 and 7
12 is the sum of 5 and 7
14 is the sum of 3 and 11
...
9990 is the sum of 17 and 9973
9992 is the sum of 19 and 9973
9994 is the sum of 53 and 9941
9996 is the sum of 23 and 9973
9998 is the sum of 31 and 9967
10000 is the sum of 59 and 9941
>

prime numbers of given range in c using loops only

how can i write a program which going to give all prime no of given range WITHOUT using ANY conditions (using just loops!) in c language. i tried many different options but non of them works properly...
for instance:
what i have already tried:
#include <stdlib.h>
#include <stdio.h>
#define UNTIL 1000
#define NOT_INCLUDED 2
int main()
{
int prime =1, i =1,factor=0;
for(prime=1;UNTIL>=prime ;prime++)
{
for( i=1;i<=prime;i++)
{
for(;prime%i==0;)
{
factor++;
}
}
for(;factor==2;factor=0)
{
printf("prime number: %d \n",prime);
}
}
return 0;
}
Challenge accepted: no conditions, hidden or otherwise
#include <stdio.h>
#include <stdlib.h> // atoi
int main(void) {
const char *p = "2 3 5 7 11 13 17 19 23 29\0\0\0\0\0"; /* extend at will */
for (;;) {
p += printf("%d ", atoi(p));
fflush(stdout);
int z = 42 / *p;
(void)z; /* unused warning */
}
return 0;
}
see code running on ideone.com
To check if N is prime, iterate through all the numbers from 2 to N to see if N is divisible by any other number. Every number is divisible by 1, so when you are testing numbers for prime, start testing against 2.
Example
#include <stdio.h>
int is_prime(int N)
{
//0 and 1 are not primes
if (N < 2)
return 0;
//start testing against 2
for(int i = 2; i < N; i++)
if(N % i == 0)
return 0; //not a prime
return 1; //prime
}
int main()
{
printf("Primes from 0 to 1000:\n");
for(int i = 0; i < 1000; i++)
if(is_prime(i))
printf("%d, ", i);
printf("\n");
return 0;
}
You can optimize the loop by changing the range to N/2.
for(int i = 2; i <= N/2; i++)
if(N % i == 0)
return 0; //not a prime
return 1;//prime

A simple program for splitting numbers does not display zeroes

I wrote a simple program in c that accepts two numbers and then splits the first number considering the digits of the second number like this:
Input:
362903157 2313
Output:
36
290
3
157
Everything works just fine, except when there are zeroes in the first number, my program skips them. For instance the upper example gives me this output:
36 293 1 570
And that is mycode:
#include <stdio.h>
int nDigits(unsigned i) {
int n = 1;
while (i > 9) {
n++;
i /= 10;
}
return n;
}
// find the highest multiple of 10
int multipleOfTen(int num){
int multiple = 1;
while(multiple <= num){
multiple *= 10;
if(multiple > num){
multiple /= 10;
break;
}
}
return multiple;
}
int main(){
int n, m, digit;
scanf("%d %d", &n, &m);
int lengthOfM = nDigits(m);
for (int i = 0; i < lengthOfM; i++){
digit = m / multipleOfTen(m); //2
for(int j = 1; j <= digit; j++){
printf("%d", n/multipleOfTen(n));
n = n% multipleOfTen(n);
}
printf("\n");
m = m % multipleOfTen(m);
}
return 0;
}
What should I change in my program so that the zeroes won't be ignored?
Instead of calling multipleOfTen() in each loop, call it once and save the result for both n and m. Then in each loop divide those results by 10
#include <stdio.h>
int nDigits(unsigned i) {
int n = 1;
while (i > 9) {
n++;
i /= 10;
}
return n;
}
// find the highest multiple of 10
int multipleOfTen(int num){
int multiple = 1;
while(multiple <= num){
multiple *= 10;
if(multiple > num){
multiple /= 10;
break;
}
}
return multiple;
}
int main(){
int n, m, digit;
int i, j;
int n10, m10;
scanf("%d %d", &n, &m);
int lengthOfM = nDigits(m);
n10 = multipleOfTen(n); //get the multiple of ten once
m10 = multipleOfTen(m);
for ( i = 0; i < lengthOfM; i++){
digit = m / m10;
m10 /= 10;
for( j = 0; j < digit; j++){
printf("%d", n/n10);
n = n% n10;
n10 /= 10;// divide by 10
}
printf("\n");
m = m % multipleOfTen(m);
}
return 0;
}
I suppose an approach like this is inadmissible?
#include <stdio.h>
#include <string.h>
int main ( void ) {
char n[64];
char m[64];
char * p = n;
int i = 0;
int c;
scanf("%63[0-9] %63[0-9]", n, m);
while ((c = m[i++]) != '\0') {
int j = c - '0';
while (j-- > 0) if (*p) putchar(*p++);
putchar(' ');
}
putchar('\n');
return 0;
}
when n=903157 and after n = n% multipleOfTen(n); n becomes 3157 not 03157 so when u dividing again in line printf("%d", n/multipleOfTen(n)); it prints 3 not 0 what you want!!
Fix your code to produce right output.

Loop doesn't end

int main(void){
int range = 0, i = 0;
printf("Enter the number of digits of the number: ");
scanf("%d", &range);
int a[range];
int b[range];
printf("Enter the number: ");
for(i = 0; i < range; i++){
scanf("%1d", &a[i]);
}
replace(a, b, range);
swap(&b[0],&b[range]);
printf("Output: ");
for(i = range; i > 0; i--){
printf("%d", b[i]);
}
return 0;
}
void replace(int *a, int *b, int n){
int *p;
int temp;
for(p = a; p < a + n; p++){
temp = ((*p + 6) % 10) / 10;
p = b;
*p = temp;
}
}
void swap(int *p, int *q)
{
int temp;
temp = *p;
*p = *q;
*q = temp;
}
My problem is with the first for loop, the loop seems to just keep taking in input and doesn't end. I tried putting a print statement before the replace method and it didn't print so I knew the problem was with the for loop. How do I fix this issue?
The replace() function is a disaster
You've now posted the replace function and it is a disaster.
void replace(int *a, int *b, int n)
{
int *p;
int temp;
for (p = a; p < a + n; p++)
{
temp = ((*p + 6) % 10) / 10;
p = b;
*p = temp;
}
}
You attempt to iterate over the array a by making p point to each element in turn. But you then, in the body of the loop, assign b to p, which places it outside the array a, which means all bets are off. It's not clear whether b is less than a + n or not — it simply isn't defined. But given that you get an infinite loop, it probably is, so your code goes reading from and writing to the same couple of locations over and over (b[0], b[1]) and p never progresses nearer to a + n.
A simple fix uses indexes:
void replace(int *a, int *b, int n)
{
for (int i = 0; i < n; i++)
b[i] = ((a[i] + 6) % 10) / 10;
}
If you want to use pointers, then:
void replace(int *a, int *b, int n)
{
for (int *p = a; p < a + n; p++)
*b++ = ((*p + 6) % 10) / 10;
}
Note that the expression evaluates to zero. The modulo 10 operation produces a value in the range 0..9 (or -9..+9), and that divided by 10 is always 0. You'll need to work on that expression.
The call to swap() is broken
You have:
swap(&b[0], &b[range]);
This definitely accesses data out of the bounds of the b array. To be safe, you need to use:
swap(&b[0], &b[range-1]);
Your output loop is broken
You have:
printf("Output: ");
for(i = range; i > 0; i--){
printf("%d", b[i]);
}
You need to avoid accessing b[range] again, and you need to output a newline at the end:
printf("Output: ");
for (i = range; i > 0; i--)
printf("%d", b[i-1]);
putchar('\n');
The input code works
The input code works, as demonstrated by this minimal adaptation of what you've got:
#include <stdio.h>
int main(void)
{
int range = 0, i = 0;
printf("Enter the number of digits in the number: ");
if (scanf("%d", &range) != 1)
{
fprintf(stderr, "Oops 1\n");
return 1;
}
printf("Number of digits: %d\n", range);
int a[range];
printf("Enter the number: ");
for (i = 0; i < range; i++)
{
if (scanf("%1d", &a[i]) != 1)
{
fprintf(stderr, "Oops 2\n");
return 2;
}
printf("Digit %d: %d\n", i, a[i]);
}
printf("Reversed input: ");
for (i = range; i > 0; i--)
printf("%2d", a[i-1]);
putchar('\n');
return 0;
}
The 'reversed input' loop is an adaptation of the 'output' loop in the question — bug-fixed to avoid accessing the array out of bounds, and using a instead of b. The error messages are very uninformative (not suitable for production work), but they're adequate to identify which statement caused an error while you're debugging.
Example run:
$ ./example-input
Enter the number of digits in the number: 12
Number of digits: 12
Enter the number: 1234 5678 9101112
Digit 0: 1
Digit 1: 2
Digit 2: 3
Digit 3: 4
Digit 4: 5
Digit 5: 6
Digit 6: 7
Digit 7: 8
Digit 8: 9
Digit 9: 1
Digit 10: 0
Digit 11: 1
Reversed input: 1 0 1 9 8 7 6 5 4 3 2 1
$
Now, adapt this into your program and see where the problem really is.
Working code
#include <stdio.h>
static void swap(int *a, int *b);
static void replace(int *a, int *b, int n);
int main(void)
{
int range = 0, i = 0;
printf("Enter the number of digits in the number: ");
if (scanf("%d", &range) != 1)
{
fprintf(stderr, "Oops!\n");
return 1;
}
printf("Number of digits: %d\n", range);
int a[range];
int b[range];
printf("Enter the number: ");
for (i = 0; i < range; i++)
{
if (scanf("%1d", &a[i]) != 1)
{
fprintf(stderr, "Oops 2\n");
return 2;
}
printf("Digit %d: %d\n", i, a[i]);
}
printf("Reversed input: ");
for (i = range; i > 0; i--)
printf("%2d", a[i-1]);
putchar('\n');
replace(a, b, range);
swap(&b[0], &b[range-1]);
printf("Output: ");
for (i = range; i > 0; i--)
printf("%2d", b[i-1]);
putchar('\n');
return 0;
}
static void swap(int *p, int *q)
{
int t = *p;
*p = *q;
*q = t;
}
static void replace(int *a, int *b, int n)
{
for (int *p = a; p < a + n; p++)
*b++ = ((*p + 6) % 10);
}
Example output
$ ./example-input
Enter the number of digits in the number: 9
Number of digits: 9
Enter the number: 123 456 789
Digit 0: 1
Digit 1: 2
Digit 2: 3
Digit 3: 4
Digit 4: 5
Digit 5: 6
Digit 6: 7
Digit 7: 8
Digit 8: 9
Reversed input: 9 8 7 6 5 4 3 2 1
Output: 7 4 3 2 1 0 9 8 5
$

Resources