c언어 구구단 Floating point exception (core dumped)오류

andycho1120의 이미지

구구단을 해결하는 코드를 작성중인데 Floating point exception (core dumped)가 뜨면서 동작을 멈춤니다.
검색이랑 숫자를 출력하는 코드를 통해 어디가 잘못된 부분인지 찾아내려고 해도 잘 안되네요.
아직 배우는 단계라 오류가 일어난 부분만 알려주시면 감사하겠습니다!

 tag block #include <stdio.h>
 
/*
 * 제작자: 
 * 제작일: 2021-3-15
 * 내용: 구구단을 자동 풀이
 * 구상한 해결 방법
 * :1.  1부터 9를 각 번째의 소수로 변환
 *  2. 빈칸에는 각 소수들을 모두 곱한 값이 기초값으로 설정되어 있고 가로, 세로줄과 3*3칸에 들어있는 숫자들을 나눗샘을 함으로써 겹치는 숫자들을 제거
 *  3. 남은 숫자들을 작은 숫자들부터 삽입시키며 순서대로 채워나감
 *  4. 더이상 진행할 수 없지만 빈칸이 남아 있으면 그 전에  채워진 칸이면 전으로 복귀, 그 숫자를 증가
 *  5. 반복
 *:
 *
 */
 
int main()
{
        int num[9][9]={{0,0,9,8,6,5,4,0,0},{0,0,9,7,4,1,2,0,0},{0,0,4,9,3,2,6,0,0},{2,8,1,5,9,7,3,6,4},{9,4,3,6,2,8,5,7,1},{6,5,7,4,1,3,9,2,8},{0,0,6,3,5,4,1,9,0},{0,0,5,2,8,6,7,0,0},{0,3,2,1,7,9,8,0,0}}; //예시용 구구단
        int num_transform[9][9]; //num_count를 담는 배열. 실질적으로 다를 배열임
        int i, j, I, J; //for 카운트
        int full_count = 81; // full_count 가 0이 되면 모든 칸이 체워짐
        int num_count = 2*3*5*7*11*13*17*19*23; //num_count를 통해 부족한 숫자가 무엇인지 판단
        int devide_arrangement[9] = {2,3,5,7,11,13,17,19,23};
 
        printf("1");
        printf("구구단을 해결하는 프로그램입니다. 구하고자 하는 빈칸은 0으로, 잘못입력했다면 119를 입력하세요\n");
        for (i=0; i<9; i++){
                for (j=0; j<9; j++){
                        //printf("%d * %d 칸의 숫자를 입력하세요", i+1, j+1);
                        //scanf("%d",&num[i][j]);
                                //if (num[i][j]==119) j = j-2;
                                if (num[i][j]!=0)full_count = full_count-1;
                }
        }
        printf("2");
        int backup[full_count][4]; //소수들의 곱을 저장하는 장치 , [][0] = 값  [][1]= 위치 i [][2] = 위치 j [][3]= devide arrangement배열 저장값 0~8 = 나누기 스택
        int x=0; // backup 카운트
 
        printf("빈칸의 갯수는 %d개 입니다.\n", full_count);
        printf("%d\n", num_count);
 
        for ( i=0; i<9; i++){           //num_count를 사용하기 위해 숫자들을 소수로 변환
                printf("1.");
                for ( j=0; j<9; j++){
                        printf("2.");
                        if (num[i][j]==0){
                                num_transform[i][j]=1;
                                backup[x][1] = i;
                                backup[x][2] = j;
                                backup[x][3] = 0;
                                x = x+1;
                                printf("3.");
                        }
                        else if  (num[i][j]==1)num_transform[i][j]=2;
                        else if  (num[i][j]==2)num_transform[i][j]=3;
                        else if  (num[i][j]==3)num_transform[i][j]=5;
                        else if  (num[i][j]==4)num_transform[i][j]=7;
                        else if  (num[i][j]==5)num_transform[i][j]=11;
                        else if  (num[i][j]==6)num_transform[i][j]=13;
                        else if  (num[i][j]==7)num_transform[i][j]=17;
                        else if  (num[i][j]==8)num_transform[i][j]=19;
                        else if  (num[i][j]==9)num_transform[i][j]=23;
                        printf("4.");
                }
        }
 
        printf("4");
        //풀이 알고리즘
 
 
        for (x=0; x< full_count; x++){
 
                backup[x][0]= num_count;
 
                i = backup[x][1]-1; //0~8
                j = backup[x][2]-1; //0~8
                for (I=0; I<9; I++){ // 세로줄 겹침 제거
                        if ( backup[x][0] % num_transform[I][j]==0) backup[x][0] = backup[x][0] / num_transform[I][j];
                }
                printf("1");
                for (J=0; J<9; J++){ // 가로줄 겹침 제거
                        if ( backup[x][0] % num_transform[i][J]==0) backup[x][0] = backup[x][0] / num_transform[i][J];
                }
                printf("2");
                for (I = i - i%3; I <= i - (i-1)%3 + 2; I++){ //같은 3X3칸의 겹침 제거
                        for (J= j - j%3; J <= j - j%3 +2; J++){
                                if (backup[x][0] % num_transform[I][J] ==0) backup[x][0] = backup[x][0] / num_transform[I][J];
                        }
                }
                printf("3");
                // 반복진행 파트
                for(I=1; I<=10;){
                        int devide_num = devide_arrangement[backup[x-1][3]];
 
                        if (backup[x-1][0]%devide_num !=0){ //안나눠짐
                                if (backup[x-1][3]==8){ //case 1 . 나누기 스택이 가득참(모든 숫자가 들어갈 수가 없음) -> 과거로 회귀해야함
                                        backup[x-1][3]=0; // 기존의 숫자 제거
                                        backup[x-2][3]++; // 이전 나누기 스택 상승
                                        num_transform[i][j]=1; //기존 숫자 제거
                                        x=x-1; //이전 숫자로 복귀
                                        I=11; //반복 탈출
 
                                }
                                else if (backup[x-1][3]!=9){
                                        backup[x-1][3]++;
                                        I++;
 
                                }
                        }
                        else if (backup[x-1][0]%devide_num ==0){ //나눠짐
                                num_transform[i][j] = devide_num;
                                backup[x-1][3];
                                I=11; //나눠짐 -> 탈출
                        }
 
                }
                printf("4");
        }
        //back up -> num transform
        /*for (i=1; i<=full_count; i++){
                J = backup[i-1][0]%10;
                I = (backup[i-1][0] - backup[i-1][0]%10 ) / 10;
                num_transform[I-1][J-1]= backup[i-1][1];
 
        } */
 
        // num transform -> num
        for (i=1; i<=9; i++){
                for (j=1; j<=9; j++){
                        if (num_transform[i-1][j-1]=2)num[i-1][j-1]=1;
                        else if (num_transform[i-1][j-1]=3)num[i-1][j-1]=2;
                        else if (num_transform[i-1][j-1]=5)num[i-1][j-1]=3;
                        else if (num_transform[i-1][j-1]=7)num[i-1][j-1]=4;
                        else if (num_transform[i-1][j-1]=11)num[i-1][j-1]=5;
                        else if (num_transform[i-1][j-1]=13)num[i-1][j-1]=6;
                        else if (num_transform[i-1][j-1]=17)num[i-1][j-1]=7;
                        else if (num_transform[i-1][j-1]=19)num[i-1][j-1]=8;
                        else if (num_transform[i-1][j-1]=23)num[i-1][j-1]=9;
 
                }
        }
 
        // num 출력
        for (i=1; i<=9; i++){
                for (j=1; j<=9; j++){
                        printf("%d ",num[i-1][j-1]);
                        if (j==9) printf("\n");
                }
        }
 
        return 0;
 
}

나빌레라의 이미지

구글에서 'floating point exception (core dumped)'로 검색하면 나오는 첫 번째 링크..

https://stackoverflow.com/questions/13664671/floating-point-exception-core-dump/13664831

이걸 보면 0으로 나머지 연산(%) 할 때 나오는 메시지라고 하네요.

코드를 보니, num_transform 배열이 0을 가지고 있지 않음을 먼저 확인하고 코드를 진행해야 할 듯 합니다.

if ( backup[x][0] % num_transform[I][j]==0)

중간에 if 문 조건에 == 도 써야 하고요.

----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

세벌의 이미지

오류가 일어난 부분만 알려주시면 감사하겠습니다!

글쎄요. 그건 본인이 찾으셔야죠. 다른 분의 힌트를 바탕으로.
core dump 뜬다면 어디서 뜨나요? 여기저기 printf 써 보면 될 거 같네요.
좀 더 전문적으로 한다면 디버거 사용법 익혀보시고요.
chanik의 이미지

gcc에 -g 옵션을 주어 디버그정보를 포함하도록 컴파일하고 gdb로 실행해 봅니다.

$ gcc 99.c -o 99 -g
$ gdb 99
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
 .
 .
(gdb) run
Starting program: /home/tester/test/99/99
1구구단을 해결하는 프로그램입니다. 구하고자 하는 빈칸은 0으로, 잘못입력했다면 119를 입력하세요
2빈칸의 갯수는 22개 입니다.
223092870
1.2.3.4.2.3.4.2.4.2.4.2.4.2.4.2.4.2.3.4.2.3.4.1.2.3.4.2.3.4.2.4.2.4.2.4.2.4.2.4.2.3.4.2.3.4.1.2.3.4.2.3.4.2.4.2.4.2.4.2.4.2.4.2.3.4.2.3.4.1.2.4.2.4.2.4.2.4.2.4.2.4.2.4.2.4.2.4.1.2.4.2.4.2.4.2.4.2.4.2.4.2.4.2.4.2.4.1.2.4.2.4.2.4.2.4.2.4.2.4.2.4.2.4.2.4.1.2.3.4.2.3.4.2.4.2.4.2.4.2.4.2.4.2.4.2.3.4.1.2.3.4.2.3.4.2.4.2.4.2.4.2.4.2.4.2.3.4.2.3.4.1.2.3.4.2.4.2.4.2.4.2.4.2.4.2.4.2.3.4.2.3.4.4I,j: 0, -1
 
Program received signal SIGFPE, Arithmetic exception.
0x000055555555595e in main () at 99.c:80
80                              if ( backup[x][0] % num_transform[I][j]==0) backup[x][0] = backup[x][0] / num_transform[I][j];

80번째 줄에서 Arithmetic exception 발생했다고 나오고 그 줄도 보여주네요.
그럼 80번째 줄에 break point 설정하고 다시 실행하여 그 줄 실행직전에 세워놓고 상태를 봅니다.

(gdb) break 80
Breakpoint 1 at 0x55555555591c: file 99.c, line 80.
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/tester/test/99/99
1구구단을 해결하는 프로그램입니다. 구하고자 하는 빈칸은 0으로, 잘못입력했다면 119를 입력하세요
2빈칸의 갯수는 22개 입니다.
223092870
1.2.3.4.2.3.4.2.4.2.4.2.4.2.4.2.4.2.3.4.2.3.4.1.2.3.4.2.3.4.2.4.2.4.2.4.2.4.2.4.2.3.4.2.3.4.1.2.3.4.2.3.4.2.4.2.4.2.4.2.4.2.4.2.3.4.2.3.4.1.2.4.2.4.2.4.2.4.2.4.2.4.2.4.2.4.2.4.1.2.4.2.4.2.4.2.4.2.4.2.4.2.4.2.4.2.4.1.2.4.2.4.2.4.2.4.2.4.2.4.2.4.2.4.2.4.1.2.3.4.2.3.4.2.4.2.4.2.4.2.4.2.4.2.4.2.3.4.1.2.3.4.2.3.4.2.4.2.4.2.4.2.4.2.4.2.3.4.2.3.4.1.2.3.4.2.4.2.4.2.4.2.4.2.4.2.4.2.3.4.2.3.4.4I,j: 0, -1
 
Breakpoint 1, main () at 99.c:80
80                              if ( backup[x][0] % num_transform[I][j]==0) backup[x][0] = backup[x][0] / num_transform[I][j];
(gdb) print num_transform[I][j]
$1 = 0
(gdb) print I
$2 = 0
(gdb) print j
$3 = -1
(gdb)

값을 찍어보니 / 및 % 연산의 나누는수 num_transform[I][j]의 값이 0 이고, 이것때문에 예외가 발생한 것이겠습니다. 그 원인은 배열 인덱스중 j가 배열의범위(0 ~ 8)를 벗어난 엉뚱한 값인 -1 을 가리키기 때문이겠고요.

이런 식으로 찾아나가면 해결하실 수 있을겁니다. 위에서 쓴 gdb 명령은 run, break, print 달랑 세 개 뿐이고 시간도 몇 분 걸리지 않습니다. gdb 기본 사용법은 https://jangpd007.tistory.com/54 에 보기 편하게 나오네요.

andycho1120의 이미지

도움많이됐습니다!

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.