-1

I'm trying to get the 10 first prime numbers but I'm having Floating point exception (core dumped) error when compiling.

#include <stdio.h>
#define MAX 50

int main(void){

FILE * fp;

int i,j,cnt=0;
int prim[MAX]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71};

fp = fopen("primeros.dat", "wb");

do{
    for (i=2; i<=100; i++){         
        for(j=0;j<=MAX;j++){
            if (i%prim[j]==0){
                continue;
            }
            else{
                fwrite(&i, sizeof(int), 1, fp);
                cnt++;
            }
        }
    }
}while(cnt<10);

fclose(fp);
return 0;

}

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261

4 Answers4

2

The problem is in the loop condition used and the values for implicitly initilized array elements. Two things to mention here

1. Excess array elements (when initializer list supplies less elements than the array size) are initialized to 0.

Quoting C11, chapter §6.7.9

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

and..

[...] If an object that has static or thread storage duration is not initialized explicitly, then:

- if it has arithmetic type, it is initialized to (positive or unsigned) zero; - if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits; [...]

2. C arrays have 0-based indexing.

So, in the code

  for(j=0;j<=MAX;j++)

problem is twofold.

  1. After the valid entries are used, you face divide-by-zero scenario in i%prim[j]. That's the cause of FPE.

    To resolve this issue, you can leave out the array size at definition time and later use sizeof to get the array size which you can use as looping condition.

  2. In case, you have MAX valid elements, for your loop, when j becomes MAX, it's out of bound access. It invokes undefined behavior.

    You should change that to

     for(j=0; j< MAX; j++)
    

    to stay withing the limit.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
2
for(j=0;j<=MAX;j++)

should be

for(j=0;j<MAX;j++)

The valid access for your array is prim[0] to prim[49] so accessing prim[50] is array out of bound access which invokes undefined behavior

Gopi
  • 19,784
  • 4
  • 24
  • 36
0

The strange program asks to discover the first 10 primes, yet already contains an array of the first 20 primes. It also causes a divide by 0 fault, because the j loop limit of MAX will cause the indexing of a 0 value in the array (but would go out of bounds anyway when j == MAX).

This solution starts by knowing that only 2 is a prime number. It builds the array of primes, using each to test further numbers for primality.

The output file is in binary format - I would have output to a text file, but as that is not the main issue I have only written the primes to console in this example.

#include <stdio.h>

#define MAX 100

int main(void){
    int i, j, cnt = 1;
    int prim[MAX] = { 2 };

    for(i=3; i<MAX; i++) {
        for(j=0; j<cnt; j++) {
            if(i % prim[j] == 0) {
                break;
            }
        }
        if(j == cnt) {
            prim[cnt++] = i;
        }
    }

    for(j=0; j<cnt; j++) {
        printf("%4d", prim[j]);
    }
    printf("\n");
    return 0;
}

Program output:

   2   3   5   7  11  13  17  19  23  29  31  37  41  43  47  53  59  61  67  71
  73  79  83  89  97
Weather Vane
  • 33,872
  • 7
  • 36
  • 56
0

This here:

for(j=0; j<=MAX; j++){

you can go only at most from 0 to max-1 [0,max)

do instead

for(j=0; j<MAX; j++){
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97