2011-10-07 5 views
3

가능한 중복 :
Best way to detect integer overflow in C/C++오버플로가 발생했는지 확인하는 방법은 무엇입니까?

이 아마 신인 질문이지만, 어떻게 좀 오버 플로우가 예를 들어 C에 내 번호의 값에 영향을 확인할 수 있습니다 정수를 곱하면, 정수 결과를 기다리고, 실제 결과가 최대 정수 값보다 크면 실제 결과가 변경됩니다 (오른쪽?). 어떻게 이런 일이 생겼는지 어떻게 알 수 있습니까?

+0

"중복 된"질문은 구체적으로 * 부호없는 * 값에 대한 것으로, 응답은이를 반영합니다. 반면에이 질문은 좀 더 일반적이지만 훨씬 까다로운 서명 된 사례를 다루고 있습니다. – caf

답변

3

서명 정수 오버 플로우는 0으로 나누기처럼 - 그것은 정의되지 않은 동작에 이르게, 그래서 당신은 잠재적으로-넘치는 작업을 실행 전에 발생하면 것인지 확인해야합니다. 오버플로가되면 모든 베팅이 해제됩니다. 코드가 아무 것도 할 수 있습니다. <limits.h>에 정의

*_MAX_MIN 매크로는 이것에 대한 유용하게,하지만 당신은 시험 자체에 정의되지 않은 동작을 호출하지 않도록주의 할 필요가있다. a * bint a, b;을 부여 오버플 예를 들어, 확인, 당신은 사용할 수 있습니다

if ((b > 0 && a <= INT_MAX/b && a >= INT_MIN/b) || 
    (b == 0) || 
    (b == -1 && a >= -INT_MAX) || 
    (b < -1 && a >= INT_MAX/b && a <= INT_MIN/b)) 
{ 
    result = a * b; 
} 
else 
{ 
    /* calculation would overflow */ 
} 

(이것은 피할 하나의 미묘한 함정 당신이 INT_MIN/-1을 계산할 수 없다는 것을 주 - 숫자가 표현할 수 보장 할 수 없습니다 실제로 공통 플랫폼에서 치명적인 트랩을 야기 함).

1

결과 숫자가 입력 값 중 하나보다 작은 경우.

a + b = c, c < => 오버플로 인 경우. 편집 : 빠름, 이것은 부호없는 정수에만 적용됩니다.

1

프로그래밍하는 동안 코드를 디버그 할 수 있습니다.

런타임에서 의미하는 경우 제한을 초과하면 작업을 수행 할 수있는 조건부를 추가 할 수 있습니다.

C는 계산량이 범위를 벗어날 때 수행 할 작업을 알지 못합니다. 피연산자를 테스트하여이를 피할 수 있습니다.

4

C99 표준에 정의되지 않은 동작이 무엇 설명이 섹션 가지고

3.4.3
정의되지 않은 동작 이식성 또는 잘못된 프로그램 구문의 사용시 또는 잘못된 데이터
행동 , 이 국제 표준은 요구 사항을 부과하지 않는다. 비고 정의되지 않은 동작은 예측할 수없는 상황을 완벽하게 무시하는 것으로서 범위는 이다. 환경의 문서화 된 방식 (진단 메시지 발행 여부와 상관없이) 또는 번역 종료 또는 진단 메시지 발행과 함께 실행으로 변환 또는 프로그램 실행 중일 수 있습니다.

정의되지 않은 동작의 예는 정수 오버플의 동작 이다.

당신은 꽤 운이 없으므로, 일반적인 경우에이를 감지 할 수있는 휴대용 방법이 없습니다.
컴파일러/구현에는 확장/지원이있을 수 있으며 이러한 상황을 피할 수있는 기술이 있습니다.
우수한 조언 : Best way to detect integer overflow in C/C++에 대해이 질문을 참조하십시오.

1

일반적으로 결과를 쳐다 보면서 오버플로가 발생했는지 알 수 없습니다. 그러나 수행 할 수있는 작업은 작업이 개별적으로 오버플로되는지 여부를 확인하는 것입니다. 예 :당신은 a와 b가 INT 년대됩니다 * B 형 오버 플로우, 여부를 확인하려면, 당신은 < = INT_MAX/B 있다면, 곱셈이 넘칠 것입니다 불평등

a * b <= INT_MAX

를 해결해야합니다.

+0

부등식의 양변을'b'로 나눌 때'b'가 음수이면 부등식을 반전해야한다는 것을 기억하십시오. 또한'b == 0'의 가능성을 잊지 마라. – caf

1

부호없는 정수로 산술을 수행하거나 서명 된 정수 오버플로가 작동하는 방식에 대한 구현 관련 보장에 의존 할 수있는 한 다양한 트릭을 사용할 수 있습니다. 그것은 빠른 될 가능성이다

unsigned int lhs = something, rhs = something_else; 
unsigned int product = lhs * rhs; 

if (lhs != 0 && product/lhs != rhs) { overflow occurred } 

하지만 휴대용입니다 : 부호없는 곱셈의 경우

, 간단한이다. 덧셈에 대한 부호없는 오버플로 검사도 매우 간단합니다. 피연산자 중 하나를 선택하고 그 합이 더 작 으면 오버플로가 발생합니다.

관련 문제