http://sckllo7.tistory.com/entry/sizeof-%EC%97%B0%EC%82%B0%EC%9D%98-%ED%95%A8%EC%A0%95




C에서 sizeof는 해당 변수 혹은 자료형의 크기를 알아 보고자 할때 쓰이며 동적 메모리 할당인 malloc을 비롯한 여러 함수와 복합적으로 사용할 경우가 적지 않게 있습니다. 그러나 이 sizeof 를 쓸 경우에는 주의해야 할 점이 있습니다.


 일단 문제 하나를 풀어 보겠습니다.

다음 소스를 실행 시키면 어떠한 결과값이 출력 될까요?


#include<stdio.h>


int main()

{

        int a = -1;


        if (sizeof(a) > a)

                printf ("sizeof(a) > a\n");

        else

                printf ("sizeof(a) < a\n");


        return 0;



 아마 sizeof(a) > a 가 출력 될 것이라는 의견이 적지 않을 것입니다.

한번 실행을 시켜 보겠습니다.



 sizeof(a) 를 하면 a가 int형여고, int형의 크기가 4byte이기에 sizeof(a)의 값은 4이고, 그냥 a는 -1 이니, sizeof(a) > a 의 조건은 4 > -1 이 되서 참인 조건 이므로 sizeof(a) > a 가 출력되야 하는데 sizeof(a) < a가 출력이 됩니다.

 왜 이런 현상이 벌어지는 걸까요?

한번 sizeof(a)와 a의 값을 출력하는 printf 문을 넣어 컴파일해 보겠습니다.


#include<stdio.h>


int main()

{

        int a = -1;


        printf ("sizeof(a) = %d\n", sizeof(a));        // 추가된 부분

        printf ("a = %d\n", a);                                   // 추가된 부분


        if (sizeof(a) > a)

                printf ("sizeof(a) > a\n");

        else

                printf ("sizeof(a) < a\n");


        return 0;


그리고 컴파일을 하면, 다음과 같이 Warning이 뜨게 됩니다.



 위에서 7번째 줄 포맷 지정자가 %d이면 int형인데 인자의 자료형은 long unsigned int 라고 나옵니다.

즉, sizeof의 반환형은 단순한 int형가 아닌 long unsigned int형이라는 말이며, sizeof(a) > a 이 비교는 같은 자료형의 비교가 아니라는 말입니다.


 다른 예를 들어 보겠습니다.


#include<stdio.h>


int main()

{

        int a = -1;

        unsigned int b = 4;


        if (b > a)

                printf ("unsigned int b > int a\n");

        else

                printf ("unsigned int b < int a\n");


        return 0;


 이것을 실행시키면 어떤 결과값이 나올까요?



 부호없는 int형을 나타낸 unsigned int와 같은 경우에는 양수만을 표시 한다는 것은 다들 아실겁니다.

그런데 C언어는 특성상 다른 자료형을 비교하거나 연산 하게 될 경우에는 두개의 피연산자 중에 큰 자료형을 가진 피연산자 기준으로 나머지 피연산자가 거기에 맞게 임시로 형 변환이 일어나게 됩니다.

 혹여나 이해가 안되시는 분들을 위하여 아래의 소스를 컴파일 해보겠습니다.


#include<stdio.h>


int main()

{

        int a = 10;

        double b = 5.3;


        printf ("a + b = %d\n", a + b);


        return 0;


 이렇게 컴파일을 하게 될 경우,



 위와 마찬가지로 포맷 지정자가 %d이면 int형인데 인자의 자료형은 double이라고 명백히 나와 있습니다. 위에서 설명한 대로 서로 다른 자료형의 두개의 피 연산자가 연산이나 비교를 하게되면 큰 피연산자 기준으로 다른 피연산자의 자료형이 임시로 바뀌는 것을 볼 수 있습니다.

 즉, 다시 원점으로 둘아가면 int형의 크기는 4byte로써 제일 앞 비트는 부호 비트로 사용되어 -2^31 ~ 2^31 - 1 의 범위의 숫자를 표현이 가능 합니다. 그러나 unsigned int형과 같은 경우에는 제일 앞 비트를 부호 비트로 사용하지 않으므로 0 ~ 2^32 - 1 의 범위까지 표현이 가능 합니다.

 ※ 아마 sizeof 의 연산된 값이 unsigned가 붙는 이유는 자료형의 크기가 0 미만일 경우가 없기 때문 인 것 같습니다.

그러므로 실질적으로 int 보다 unsigned int 가 더 큰 값을 표현 할 수 있기에 if문 안에서 int형과 unsigned int형의 비교가 이루어 질때unsigned int 기준으로 int형이 임시로 unsigned int 형으로 변경이 되나 a의 값이 -1이기에 내부에서 값은 그래도이나 강제형 변환이 일어나 unsigned int의 최고 값인 4294967295 (2^32 - 1 ) 으로 바뀌므로 소스에서는 sizeof(a) > a 가 4 > -1 로 비교 되는 것이 아니라 4 > 4294967295 로 연산이 되기에 해당 비교문이 거짓으로 나오게 되며, 결론적으로는 sizeof(a) < a 가 출력이 되게 되는 겁니다.

'미분류' 카테고리의 다른 글

windbg 명령어 모음  (0) 2016.01.12
python exploit 연습용  (0) 2015.11.27
codegate vuln - 300  (0) 2015.11.27
PEDA 튜토리얼  (0) 2015.11.27
LOB fedora  (0) 2015.11.09

+ Recent posts