Segmentation Fault during printing, includes large array computation - c

This program in C is supposed to delete every 666th number in a series of 10^7 natural numbers.
The problem seems to compile fine, even with optimisation. But, while on runtime stops throwing a Segmentation Fault after a few computations. I notice that when it stops its a few hundred thousand natural numbers away from the upper limit of 10^7. I at first tried to solve the problem using dynamic memory allocation with malloc. I received the same output. I tried using static arrays to do the job.
#include <stdio.h>
static unsigned int a[10000001] = {[0 ... 10000000] = 1};
void main(void) {
unsigned int i = 1, last = 0, count = 0, test = 0;
while(i < 100000) {
count = 0; test = 0;
while(count < 665) {
if(a[last + count + test])
count++;
else
test++;
}
last = last + test + count;
if(last < 10000002)
a[last] = 0;
else {
last = last - 10000001;
a[last] = 0;
}
printf(" %u", last);
i++;
}
printf("\n\n");
}

Here's one problem:
if(last < 10000002)
a[last] = 0;
Should be:
if(last < 10000001)
a[last] = 0;
Also, this statement might be an issue if last + count + test is > 10000000:
if(a[last + count + test])

Related

function fact_of_ k returns segmentation fault, when k is 0

I want to know why this program gives me a segmentation error. Kindly note that I've solved this problem by changing the value of variable k from 0 to 1. Though it solved my problem, I want to know what happens with the logic/system when k is 0?
#include <stdio.h>
#include <stdlib.h>
int fact_of_nk(int);
int fact_of_k(int);
int fact_of_n(int);
int main()
{
int fact_n, fact_k, fact_nk, bmu, k = 0, nk;
for (int n = 1; n <= 10; n++)
{
fact_n = fact_of_n(n);
while (k <= n)
{
fact_k = fact_of_k(k);
int nk = (n - k);
printf("%d ", nk);
k++;
}
k = 0;
printf("\n");
}
return 0;
}
int fact_of_n (int number)
{
if (number == 1)
return 1;
else
return number * fact_of_n(number - 1);
}
int fact_of_k (int choose)
{
if (choose == 1)
return 1;
else
return choose * fact_of_k(choose -1);
}
int fact_of_nk (int choose)
{
if (choose == 1)
return 1;
else
return choose * fact_of_nk(choose - 1);
}
Your code gets a segmentation fault because of recursion. Look at what happens in your program. You pass k to fact_of_k. k is 0, and 0 != 1. So it calls fact_of_k again, this time with 0 - 1, so -1. -1 is not one, so it calls fact_of_k again, this time passing -2. You can see the problem. Using recursion too much gets a segmentation fault, which is why your program doesn't work.
You get a stack overflow here because the recursion never ends if you call fact_of_k(0)
int fact_of_k(int choose)
{
printf("Choose = %d\n", choose); // <<<< add this
if (choose == 1)
return 1;
else
return choose * fact_of_k(choose - 1);
}
Check this modified function and see what the output is, you'll understand.
Hint for correction: modify slightly this line:
if (choose == 1)

Writing a txt file while running some calculations

I am trying to create a program that outputs in a txt file the results of Collatz conjecture. However when I try to do it with big numbers, like 1,000,000, it does not work properly and always stops at 113383.
Here is the code:
int n, count, number, mayor, masvueltas, top;
char c = '#';
freopen("output MILLION.txt", "w", stdout);
count = 0;
number = 1;
mayor = 0;
masvueltas = 0;
while(number != 1000000) {
printf("\n%d did ", number);//this will say that number did COUNT loops
n = number;
while (n != 1) {
if (n % 2 == 0) {
n = n / 2;
count++;
}
else {
n = 3 * n + 1;
count++;
}
}
printf(" %d saltos.\n", count);//Here continoues the sentence
char graf[count];//creates an array to print the # character COUNT times
for (int i = 0; i < count; i++) {
graf[i] = c;
printf("%c", graf[i]);
}
if(masvueltas < count) {
masvueltas = count;
mayor = number;
}
number++;
count = 0;
}
Also if you know how to print the ASCII character 219, block, in a txt file it would be great. Is not important just so I have a cleaner txt file.
This happened because for number = 113,383 the calculations reach the value of 827,370,449 after 119 counts, the next count max the value 2,482,111,348 which is more than the maximum value of int variable 2,147,483,647, which makes the value of n becomes negative, -1812855948, and the loop fails to reach 1. You should use long long n instead to get the results you want. I also recommend that you use for loop instead of while loop.

Program to find if a number is perfect

I'm having trouble trying to run this program that I made to find if a number if perfect. It gives me a segmentation error. What does that mean? Can you help me to understand what I did wrong? Here's my code:
#include <stdio.h>
void perfect(int number);
int main() {
int n;
printf("Insert a number greater than 0: ");
scanf("%d", &n);
perfect(n);
return 0;
}
void perfect(int number) {
int i, j, array[100], k = 0, tmp = 0, tmp2 = number;
for (i = 2; i <= 1000; i++) {
for (j = 2; j <= 1000; j++) {
if (i % j == 0) {
array[k] = i;
k++;
}
}
}
k = 0;
while (tmp2 != 1) {
if (tmp2 % array[k] == 0) {
tmp += array[k];
tmp2 /= array[k];
}
k++;
}
tmp++;
if (tmp == tmp2) {
printf("It's a perfect number\n");
}
}
The segmentation fault tells you that you are trying to access memory outside the bounds of what you are allowed. Your array is nowhere near big enough for what your program does.
You need to reconsider what you are storing in array. All numbers up to a thousand that are divisible by other numbers, right? But actually it's going to be
all of them and
all the even ones and
all of them that are divisible by 3 and
all of them that are divisible by 4 etc.
That sounds like a lot more than 100 doesn't it? There will also be many, many repeats which I doubt you intend. For example, you will store 6 three times as it is divisible by 2, 3 and itself. (So, by the way, you should stop looking once j is greater than i.)
Your while loop is also peculiar. It terminates when tmp2 is 1. How is tmp ever going to be equal to 1?
Back to the drawing board, I'm afraid!
Given the loop index maximum value 1000, the array array should be defined with a size of at least 1001. With a size of 100, you likely have a buffer overflow causing undefined behavior.

Decimal to Binary conversion with quotient in C

I try to create a program which converts Decimal to Binary and back. My problem is when the fraction part becomes too big in binary, my program crashes. I tried many different approaches to this problem and none of them worked...I dont know why it happens so I have no sollution for it.
This program contains only the issue.
Please help me.
example1: 10 10.5 -> Program works fine
example2:10 10.23 -> Program crashes
Above are examples.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main(){
int base;
double number;
scanf("%d %lf",&base,&number);
if(base == 10){
//Integer Part
int n = (int)number;
number = number - (double)n;
int i = 0;
char *binaryfirst;
binaryfirst = malloc(sizeof(char*));
while(n != 0){
binaryfirst[i] = (n % 2) + '0';
n /= 2;
i++;
}
binaryfirst[i] = '\0';
strrev(binaryfirst);
//printf("%lf\n%s\n",number,binaryfirst);
//Fractional part
int j = 0;
char *binarysecond;
binarysecond = malloc(sizeof(char*));
//This is The part where I am lost...
for(j = 0; j < 60; j++){ //60 is the maximum length that it can become
number *= 2;
if(number >= 1.0){
binarysecond[j] = '1';
number = number - 1;
}else if(number == 0){
binarysecond[j] = '0';
break;
}else{
binarysecond[j] = '0';
}
printf("%lf; %c\n",number, binarysecond[j]);
}
printf("%d\n",j);
binarysecond[j] = '\0';
//printf("\n%s\n",binarysecond);
//Memory "Let it go"!!!!
/* for(i = 0; i < sizeof(binaryfirst); i++){
free(binaryfirst[i]*2);
}*/
free(binaryfirst);
/* for(j = 0; j < sizeof(binarysecond); j++){
free(binarysecond[j]);
}*/
free(binarysecond);
}
return 0;
}
This:
binaryfirst = malloc(sizeof(char*));
and
binarysecond = malloc(sizeof(char*));
allocates the size of a pointer, but the loop that writes to it makes it clear that it expects to store at most 60 bytes at that location. This makes no sense at all; C does not magically grow the allocation when you write outsite it, instead you get undefined behavior.
If you're unsure about heap memory allocations, and they're not crucial to the problem you're trying to solve, first do it without any. Just use simple arrays:
char binaryfirst64];
char binarysecond[64];

Segmentation Fault 11 with recursive function in C

I keep receiving a Segmentation Fault 11 for the following code. I believe it has something to do with recursion but I'm not entirely sure how. The method should take in an array, skip the odd values, and keep repeating until it has an array with only value left and returns that value.
Thanks!
#include <stdio.h>
int callTable(int table[], int size)
{
int i = 0;
int j = 0;
int cHeight = size / 2;
int cTable[cHeight];
while (i < size)
{
if (table[i] % 2 == 0)
{
cTable[j] = table[i];
j++;
}
i++;
}
if (size > 1)
return callTable(cTable, cHeight);
else
return cTable[0];
}
int main()
{
int tPass[100];
int i, answer;
for (i = 0; i < 100; i++)
tPass[i] = i + 1;
answer = callTable(tPass, sizeof(tPass) / sizeof(tPass[0]));
printf("%d\n", answer);
}
Do you want to skip the odd values or the odd indexes? You are currently skipping the odd values, so after you call callTable once, there are only even values left. Then, on the second call, you try to use an array of half the size to store the even values (which are all of them), so you try to store the entire array on another with half the size.
If you intended to skip the odd indexes, then change this line:
if (table[i]%2==0)
for this one:
if (i%2==0)
That runs fine and returns 1 (which is the number with index 0).

Resources