2016-09-18 2 views
1

프로그래밍 웹 사이트에서 문제가 해결되었지만 입력이 n = 2147483647 인 경우 세그멘테이션 오류 (코어 덤프)가 발생합니까?세분화 오류 (덤프 처리)?

int integerReplacement(int n) { 
    if(n == 1) 
    return 0; 
    if(n%2 == 0) 
    { 
    return 1+integerReplacement(n/2); 
    } 
    else 
    { 
    int lMin = 1+integerReplacement(n-1);  
    int rMin = 1+integerReplacement(n+1); 
    return lMin<rMin?lMin:rMin; 
    } 
} 
+4

스택 오버플로? – Raman

+9

재귀가 당신의 명시된 인자'2147483647'을 받으면'n'이 정수 범위를 벗어 났기 때문에'integerReplacement (n + 1);은 * 정의되지 않은 행동 *입니다. –

답변

0

Weather Vane이 올바르게 명시된 것처럼 INT_MAX + 1은 정의되지 않은 동작을 가져옵니다. 여기

은 당신이 알아 낸 수있는 방법입니다 : 그래서 당신은 일반적으로 31 개 이상의 시간이 재발하지 않아야 알고리즘,하지만 때문에 서명 오버 플로우 끝까지 스택 오버 플로우 (끝낼 사실에 할

gcc -g foo.c 
gdb -q ./a.out 
(gdb) r 
Starting program: /tmp/a.out 

Program received signal SIGSEGV, Segmentation fault. 
0x00000000004004f5 in integerReplacement (n=<error reading variable: Cannot access memory at address 0x7fffff7fefec>) at foo.c:1 
1 int integerReplacement(int n) { 
(gdb) bt 6 
#0 0x00000000004004f5 in integerReplacement (n=<error reading variable: Cannot access memory at address 0x7fffff7fefec>) at foo.c:1 
#1 0x0000000000400522 in integerReplacement (n=-2) at foo.c:6 
#2 0x0000000000400534 in integerReplacement (n=-1) at foo.c:10 
#3 0x0000000000400522 in integerReplacement (n=-2) at foo.c:6 
#4 0x0000000000400534 in integerReplacement (n=-1) at foo.c:10 
#5 0x0000000000400522 in integerReplacement (n=-2) at foo.c:6 
(More stack frames follow...) 

(gdb) bt -10 
#174684 0x0000000000400522 in integerReplacement (n=-16777216) at foo.c:6 
#174685 0x0000000000400522 in integerReplacement (n=-33554432) at foo.c:6 
#174686 0x0000000000400522 in integerReplacement (n=-67108864) at foo.c:6 
#174687 0x0000000000400522 in integerReplacement (n=-134217728) at foo.c:6 
#174688 0x0000000000400522 in integerReplacement (n=-268435456) at foo.c:6 
#174689 0x0000000000400522 in integerReplacement (n=-536870912) at foo.c:6 
#174690 0x0000000000400522 in integerReplacement (n=-1073741824) at foo.c:6 
#174691 0x0000000000400522 in integerReplacement (n=-2147483648) at foo.c:6 
#174692 0x0000000000400547 in integerReplacement (n=2147483647) at foo.c:11 
#174693 0x0000000000400567 in main() at foo.c:18 

스택이 다 떨어지기 전에 174693 번 되풀이).

+0

이 답변은 thnx ...하지만 의심의 여지가 있습니다. gcc는 정수로만 31 스택을 만듭니다 ??? –

+0

@RaviSingh 정수는 대부분의 현재 아키텍처에서 31 비트 (더하기 부호 비트)를 갖습니다. 이는 0 또는 1에 도달하기 전에 2로 나눌 수있는 횟수를 제한합니다. –