티스토리 뷰

카테고리 없음

[씨] itoa () c 구현 int min underflow

필살기쓰세요 2021. 2. 8. 19:48

이 줄 :

당신이 생각하는대로하지 않습니다. C에는 음의 정수 상수가 없습니다. 이것은 단항 빼기 연산자를 적용하는 값이 2 ^ 31 인 부호없는 정수입니다. 즉,

x == -21...

컴파일러가 사용하는 C 표준에 따라 표현식 이 달라집니다.C99 또는 C11을 사용하면 괜찮습니다. 충분히 큰 부호있는 유형이 있습니다. long long은이 숫자에 대해 충분히 큰 것이 보장되므로 x와 -21 ... 둘 다 long long으로 변환 된 다음 비교됩니다. 그러나 C89 컴파일러를 사용하고 있고 컴퓨터에 충분한 형식이없는 경우 여기에서 구현 정의 동작을 수행합니다.

정수가 더 작은 크기의 부호있는 정수로 강등되거나 부호없는 정수가 해당 부호있는 정수로 변환 될 때 값을 표시 할 수없는 경우 결과는 구현에서 정의됩니다.

이것이 사람들이 한계를 사용하라고 말하는 이유입니다. 그들이 현학적이기 때문이 아니라 이것은 위험한 영역이기 때문입니다. limits.h에 포함 된 내용을 자세히 살펴보면 다음과 같은 줄을 찾을 수 있습니다.

이 표현식에는 실제로 올바른 유형과 값이 있습니다.그 외에는 게시 한 코드에서 오류를 볼 수 없습니다. 이것이 문제가 아니

ft_intlen

거나

ft_strdup

잘못된 경우. 또는 테스트에서 함수를 잘못 호출하고 있습니다 (테스트를 호출 할 때 -21 ...에도 동일한 문제가 적용됨).-------------------
상태 : 유효하지 않은 해결이유 : WORKS_FOR_ME어쨌든 몇 가지 점이 향상되었습니다.

  • sizeof(char) 항상 1이며 필요하지 않습니다.
  • 캐스트하지 마십시오 malloc
  • 특별한 경우 0을 처리하면 한 번에 처리하십시오.
  • -2147483648매우 나쁩니다. 그게 INT_MIN목적입니다.
  • return은 함수가 아니므로 return하지 말고 (value)return value합니다.
  • s[len - 1]좋은 감소, 모든 시간을 len루프를 입력하기 전에. 또는 호출 len + 1에서만 필요 하므로 반환하고 다음을 사용하여 호출하십시오.malloclenintlenmalloclen + 1

ft_itoa.c

main.c

결과

-------------------
그 수표는 필요하지 않습니다. 대신

unsigned

절대 값에 맞는 로 변환하십시오 .

이것은 인수에

size_t ft_uintlen(unsigned)

대해 작동 하는 새로운 함수를 사용합니다

unsigned

.-------------------
오버플로 방지 메커니즘에 문제가있을 수 있습니다.

x

type

int

을 사용

n

하여 유형 을 할당하려고 합니다

long int

. 그러나 사양은 유형

long int

이 다음보다 큰 값 범위를 처리 할 수 있음을 보장하지 않습니다

int

. 더 많은 정보는

"Long Vs. Int"

에서 찾을 수 있습니다 .컴파일러가 지원하는 경우

long long int

유형을 사용하십시오

n

. 귀하의 업데이트

ft_intlen

에 기능

int ft_intlen(long long int n)

. 이 경우 전체

int

유형 값 범위 를 처리 하고 다음 행을 제거 할 수 있습니다.

또한 오류 메시지

did not allocate memory for the int min value

시스템 오류 번호

중 하나가 아닙니다 . 특히 어떤 이유로 든 디버깅 할 수없는 경우 애플리케이션에 더 많은 로그인을 추가해야합니다.

errno

각 시스템 기능 호출을 확인하십시오 . 예 :

-------------------
의심되는 순서대로 잠재적 인 코드 오류 :

  1. ft_strdup() 그 코드는 "int min value"로 호출되고 오류가 발생합니다.
  2. 다양한 기능이 부족한 프로토 타입. 특히 ft_strdup()/strdup().
  3. 호출 / 테스트 코드에 결함이 있습니다.
  4. "int min value"가 -2147483648보다 큽니다. (사용하는 것이 좋습니다 INT_MIN.)
  5. ft_intlen(n)잘못 코딩되고 반환 된 INT_MAX다음 코드가 시도합니다 malloc(INT_MIN).
  6. int/long둘 다 64 비트. 이것은 첫 번째 s[len - 1] = (n % 10) + '0';INT_MIN.

그렇지

INT_MIN

않고 값이 -2147483648이면

ft_itoa(int x)

괜찮습니다.


OP는 "... strdup은 문자열을 할당하고, ft_intlen은 문자열의 길이를 반환하며, 둘 다 테스트 케이스를 통과합니다. – franklinexpress Oct 8 at 7:52"테스트 케이스를 통과한다고해서 정의되지 않은 동작을 호출하지 않고 작동한다는 의미는 아닙니다. 베스트 게시하려면

ft_intlen()

,

ft_strdup()

및 검토를위한 테스트 장치.


 

이식 가능한

구현 후보 .

int/long

크기 또는 2의 보수 에 의존하지 않습니다 . 너무 많은 가용성을 희생하지 않고 코드 가 8이라고 가정 할 수 있는 것

<limits.h>

외에는 필요 하지 않습니다. C89 / 99 / 11에서 작동합니다.

CHAR_BIT

 

-------------------
당신이 준 코드는 OsX에서 컴파일되고 작동하지만, 내 자신

ft_stdup

ft_intlen

. 따라서 코드를 보여 주거나 오류를 확인할 수 있습니다. 몇 가지 테스트를 수행했습니다 (2147483647, -2147483648 포함). 잘 작동합니다.어쨌든, 라인 :

if (x == -2147483648) return (ft_strdup("-2147483648"));

어떤 종류의 작업을 수행하기 전에

x

값을

long long

변수 (

Art

)에 복사하는 한 쓸모가 없습니다 . 따라서 포함 할 필요가 없습니다

types.h

(악명 높은 물랑이는 -42를주지 않음).OsX에서는

long

에서도 작동 하지만 휴대용 안전하지 않습니다.-------------------
다음을 사용하십시오.

대신에:

테스트에서 :

그 이유는 일부 컴파일러가 해당 숫자를 이해하는 데 문제가있을 수 있기 때문입니다.표준 C 라이브러리

limits.h는

일반적으로 다음과 같이 정의합니다.

이 문제를 피하기 위해.

출처
https://stackoverflow.com/questions/39929982

댓글
공지사항
Total
Today
Yesterday
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30