Why does the code return error dumped core?

Asked

Viewed 42 times

-2

I came across the following errors: floating point Exception and dumped core for the same code. I did not understand very well why this error occurred. I put the code in a Bugger and from what I saw the scanf is not reading any number. How can I fix this?

#include <stdio.h>
#include <stdio.h>
#include <stdbool.h>
#include <math.h>

int n, i = 0, j = 0;
bool x;

bool is_prime(int num)
{
    while(i <= 20)
    {
      if(num % i == 0)
        j++;
      i++;
    }
    if(j > 2)
    {
      return false;  
    }
    else
      return true;
}

int main()
{
  scanf("%d", &n);
  printf("%d", is_prime(n));
  return 0;
}
  • 3

    Like i starts at zero, you end up making a division by zero in num % i (for the operator % is the rest of the division, and since it cannot be divided by zero, it is an error). Do the i start at 1 (and do this within the function instead of creating i out of it, otherwise you will only be able to use the function once). Also, why the stop condition is i <= 20? If you enter a number greater than 20, it won’t count all divisors correctly, it should be i <= num

1 answer

1


int n, i = 0, j = 0;
bool x;

bool is_prime(int num)
{
    while(i <= 20)
    {
      if(num % i == 0)
        j++;
      i++;
    }
    if(j > 2)
    {
      return false;  
    }
    else
      return true;
}

Don’t write like that. These variables with these simple names, i, j n declared outside any function become global and valid throughout the code. That means any part of your program that uses a i will be using the same i. Do you know how long it takes for it to fall on your head when you use by mistake a j in two places? minutes. And how long does it take to find the error and fix it? What if the program doesn’t have only 20 lines? ...

Never use anything global. And after all it is forbidden everywhere same.

int main()
{
  scanf("%d", &n);
  printf("%d", is_prime(n));
  return 0;
}

Don’t write like that either. Have a manual? A book? Read the documentation before using scanf()? Use an IDE that shows the prototypes of the functions?

  • scanf() returns a int with the total values you were able to read. In your case you tried to read one using such %d. So scanf() will return 1 if read, or 0 if not read or -1 if given any error. Only you have not tested ANYTHING and followed blindly. What is the purpose of knowing that a number you do not know whether or not read is prime?
  • and that line
  printf("%d", is_prime(n));

ends up being a disaster: it was your hope to know if you read something and what is going to function is_prime(). But how did you join the printf() and the call to is_prime() in the same command until the use of the Bugger was impaired because it cannot stop in the middle of the line. While you are learning or at least while you are testing never do so. write separately

    printf("%d foi o valor lido\n", n );
    printf("%d foi o retorno de is_prime (0 = nao primo)\n", is_prime(n));

And you’ll know if the show canceled because you read some trash or if is_prime() cancelled, and with what value of n. And of course declare n in there. Something like that would be safer:

int main(void)
{
    int n = 0;
    if ( scanf("%d", &n) != 1 )
    {
        printf("Não leu nada. Encerrando\n");
        return -1;
    };
    printf("%d foi o valor lido\n", n );
    printf("%d foi o retorno de is_prime (0 = nao primo)\n", is_prime(n));
    return 0;
};

And is_prime()

What does the 20 there mean? What is the logic of what you are writing? The simple one to identify a cousin N so it is

  • divide N by values i as it did, lower values than N and if N is multiple of i return false.
  • how far to go with i? up to 20? until N-1? No, of course. If N is multiple of i then of course you have a j such that i * j == N
  • as it grows i j decreases, right? For example 12 is multiple of 2, 3, 4 and 6. So for the largest i has the smallest j: 6x2 = 12. For the smallest i has the largest j clear: 2x6 = 12. And they can be equal: 5 * 5 == 25 and only then discovers that 25 is not prime. So the greatest value you need to test is the square root of N...
  • to avoid having to use square root --- sqrt() in C --- and having to include Math. h and call a function that can take an eternity relative to a simple multiplication, can even use another condition: look for multiples i until i*i be greater than N, exchanging the square for the square root.
  • can use more expressive names, and declare the variables where they will be used because it is safer like this. Something like this should work:
bool is_prime(int N)
{
    int divisor = 2;
    if ( N == 2 ) return true;
    while( divisor * divisor <= N )
    {
      if ( N % divisor == 0) return false;
      divisor += 1;
    }
    return true;
}

And you may agree it’s easier to read.

But since it’s a loop and it starts with two and ends with an objective condition, then one for can be safer and can use like this:

bool is_prime(int N)
{
    if ( N == 2 ) return true;
    for( int divisor = 2; divisor * divisor <= N; divisor +=1  )
      if ( N % divisor == 0) return false;
    return true;
}

And see

[Identificando primos]. Valor: 3
3 foi o valor lido
1 foi o retorno de is_prime (0 = nao primo)

about main() and a complete example with the 2 functions

This is a show that only does one thing and only does it once. It is very annoying to run the program and wait for it to ask the number and then digest the number and it shows the number and give the answer. In general when the guy runs the program already has a number in mind ;)
It’s much more comfortable to just use the command line, and write something like that

#include <stdio.h>
#include <stdlib.h>

char is_prime(int);
char is_prime_while(int);

int main(int argc, char** argv)
{
    int n = 0;
    if ( argc < 2)
    {
        printf("[Identificando primos]. Valor: ");
        if ( scanf("%d", &n) != 1 )
        {
            printf("\nNão leu nada. Encerrando\n");
            return -1;
        };
    }
    else
    {
        n = atoi(argv[1]);
    };
    printf("%d foi o valor lido\n", n );
    if ( is_prime(n))
        printf("%d e' primo!\n", n);
    else
        printf("%d nao e' primo!\n", n);
    return 0;
};

char is_prime(int N)
{
    if ( N == 2 ) return 1;
    for( int divisor = 2; divisor * divisor < N; divisor +=1  )
      if ( N % divisor == 0) return 0;
    return 1;
}

char is_prime_while(int N)
{
    int divisor = 2;
    if ( N == 2 ) return 1;
    while( divisor * divisor < N )
    {
      if ( N % divisor == 0) return 0;
      divisor += 1;
    }
    return 1;
}
// fim do texto

And then you can use both ways:

so$ gcc -o primo -Wall -O3 y.c
so$ ./primo
[Identificando primos]. Valor: 25
25 foi o valor lido
25 nao e' primo!
so$ ./primo
[Identificando primos]. Valor: 11
11 foi o valor lido
11 e' primo!
so$ ./primo 121
121 foi o valor lido
121 nao e' primo!
so$ ./primo 
[Identificando primos]. Valor: w

Não leu nada. Encerrando
so$ 

That is to say,

  • if the guy type 'primo 22' the program uses 22
  • if the guy type only the name of the program, 'primo' the program reads (and first warns what it will read)
  • if the guy is going to type and hits his hand on a letter p[or mistake the program does the simple and says that it has not read anything.

about bool

C zero is false. The rest is true. And so use stdbool only for constant power true and false and declare little things as bool that will occupy after all at least one byte even is a little too much for my example :)

a slightly smaller progamma

Once you are a little safer with reading and the result can use something more compact, using a single printf() and left the messages ready to give up the test. is_prime() returns 0 for fake and 1 for real then

    const char* msg[] = { " nao e' primo", " e' primo" };
    printf("%d %s\n", n, msg[ (int)is_prime(n)] );

is slightly smarter. The program could then be only

#include <stdio.h>
#include <stdlib.h>

char is_prime(int);

int main(int argc, char** argv)
{
    int n = 0;
    if ( argc < 2)
    {
        printf("[Identificando primos]. Valor: ");
        if ( scanf("%d", &n) != 1 )
        {
            printf("\nNão leu nada. Encerrando\n");
            return -1;
        };
    }
    else
    {
        n = atoi(argv[1]);
    };
    const char* msg[] = { " nao e' primo", " e' primo" };
    printf("%d %s\n", n, msg[ (int)is_prime(n)] );
};

char is_prime(int N)
{
    if ( N == 2 ) return 1;
    for( int divisor = 2; divisor * divisor <= N; divisor +=1  )
      if ( N % divisor == 0) return 0;
    return 1;
}
// fim do texto

Browser other questions tagged

You are not signed in. Login or sign up in order to post.