• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

8:12 경에 질문있습니다.

20.04.27 11:05 작성 조회수 147

0

구글에 검색을 해보니 , 메모리상에서 주소는 부호없는 정수로서 구현된다는데 어떻게 -16이라는 음수값이 주소로 나타나지는지 궁금합니다. 실제 주소를 의미하는것이 아닌 단순히 수치만 그렇게 계산이 된건지 아니면 실제 존재하는 주소값이 연산의 결과로 나온것인지 궁금합니다. 

답변 4

·

답변을 작성해보세요.

1

아아

/

1111111111111111111111111111111111111111111111111111111111110000

 와 같은 double형에 대해 오버플로우가 두번 일어난 주소값(이진수)를 

/

이 부분때문에 오버플로우 또는 언더플로우는 한번만 일어난다는 설명해주신것 같은데 제가 표현을 잘못했습니다 ㅎㅎ 주소0 에서 double형만큼 뒤로 두번 갔다는 뜻이였습니다.

매번 정말 감사드립니다!!

1

코드쉼터님의 프로필

코드쉼터

2020.04.29

언더플로우는 한번만 일어났습니다. (0 에서 더 작아질 때 한번만 발생합니다.)

오버플로우는 반대의 의미로 해당 메모리가 이미 표현할 수 있는 최대치에 도달했는데 추가적으로 더 더해질때 일어납니다.

예를들어 0xFFFFFFFF 에 0x00000001 을 더하면 발생합니다.

나머지는 잘 이해하셨습니다!

1

아 감사합니다!

요약하면 , 메모리 주소는 이진수이고  , 기본적으로는 부호없는 정수를  의미하는것이고 

1111111111111111111111111111111111111111111111111111111111110000

 와 같은 double형에 대해 오버플로우가 두번 일어난 주소값(이진수)를 해당 시스템에서 메모리의 주소와 같은 비트인 부호있는 정수 자료형(여기서는 long long 형) 에 그대로 대입하면(즉 , long long 형으로 캐스팅) 2의보수에따라 -16이 되는것이기에 우리의 직관적 연산 (8씩 두번뺌 )과도 일치하는것이지만  

만약 ptr -- 를 계속반복하여  , ptr의 값이 이진수로서는 011111~.....11 (즉 , 맨 첫번째 비트가 0) 이 되는 순간부터는 long long 형으로 캐스팅 하더라도 그값이 (-8)*n (n은 자연수) 가 되는것이 아니라 , 어떠한 양의 정수의 값이 되는거겠네요??

1

코드쉼터님의 프로필

코드쉼터

2020.04.27

해당 예제는 포인터에 언더플로우를 유도하면 어떻게 되는지에 대한 내용인 것 같습니다.

컴퓨터는 주소를 포함해서 수를 저장할때 음수이건 양수이건 결국엔 동일한 2진수로밖에 저장할 수 없습니다.

그렇기 때문에 우리가 C언어에서 메모리를 읽을때 자료형 또는 형식 지정자 등을 꼼꼼히 명시해줘야 하는 것입니다.

 

예를들어 같은 이진수 1000 0000 라도

1 바이트 (8 비트) 부호있는 정수로 해석하면 -128 이 되고,

(2의 보수 표현법에서 맨 앞자리가 1이면 음수로 생각하시면 쉽습니다.)

1 바이트 (8 비트) 부호없는 정수로 읽으면 128 이 되는 것입니다.

이는 음수던 양수던 메모리를 최대한 활용하기 위해서 이렇게 만들었다고 생각하시면 됩니다. (2의 보수 표현법)

(음수값 "128" 을 쉽게 구하는 방법은 위의 경우 자료형(메모리 크기) 가 8비트로 되어있는데, 8비트로 표현할수 있는 모든 경우의 수 256. 즉, 이진수 1 0000 0000 값에다가 위의 2의 보수로 표현된 이진수 1000 0000를 빼주면 쉽게 도출할 수 있습니다.)

 

다시 강의 예제로 돌아가보면 ptr이 원래 가지고 있던 수는 0 입니다. (NULL 이랑 같군요..)

0x00000000

이진수로 표현하면 아래와 같습니다.

0000000000000000000000000000000000000000000000000000000000000000

 

그다음 ptr = ptr - 2 를 하게 되면 ptr 의 값은 0 에서 -2 * 8 (메모리 접근 단위가 1바이트 씩이고, long long 이 8바이트 크기인 것 배우셨죠?) 즉, -16 로 바뀌어야 합니다.

컴퓨터 메모리에 -16 을 저장하려면 어떻게 적어서 넣어야 할까요?

네 맞습니다. 2의 보수 표현법으로 넣어야 합니다.

 

따라서 다음과 같이 ptr 에 들어있는 값이 바뀌게 되는 것입니다.

0xFFFFFFF0

이진수로 표현하면 다음과 같습니다.

1111111111111111111111111111111111111111111111111111111111110000

  

+

강의에서는 아마 실험적인 의도로 포인터의 주소를 부호가 있는 긴 긴 정수형 (%lld) 으로 출력해 본 것 같습니다.

사실상 실제로 프로그래밍을 하실때 이렇게 쓰실 일은 없다고 보셔도 좋습니다.

포인터의 값(주소)를 출력하려면 형식 지정자를 포인터형 (%p) 으로 사용하는 것이 맞겠지요...

 

+

0000000000000000000000000000000000000000000000000000000000000000

에다가 -1 을 하면 어떻게 될까요?

언더플로우가 나면서

1111111111111111111111111111111111111111111111111111111111111111

가 됩니다.

참고 - https://dojang.io/mod/page/view.php?id=32