프로그래밍

ZeroMemory, memset, 구조체={0} 의 차이

지니아부지 2011. 7. 30. 18:11
출처 : http://reister.tistory.com/tag/%EA%B5%AC%EC%A1%B0%EC%B2%B4%EC%B4%88%EA%B8%B0%ED%99%94



여러분은 구조체를 초기화 할 때, 어떤 방법을 쓰십니까?

0으로 채워야 한다면요,.

 

보통 세가지 방법들을 많이 쓰실겁니다.

 

먼저 Original C에서 부터 즐겨 사용되어 오던 memset()함수가 있겠고요,

둘째로, 윈도우 프로그래밍에서 자주 사용되는 ZeroMemory 매크로도 있구요

제가 즐겨 사용하는 Struct s = {0}; 등이 있지요.

 

뭐가 다를까요? 은근히 이걸 잘 모르시는분들이 많더라고요.

 

그래서 직접 보여드립니다.

 

우선 간단한 테스트 코드를 작성하고요.

#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
    struct S{
        int a;
        int b;
        int c;
        int d;
        char e[20];
    };

 

    S s1;
    ZeroMemory(&s1, sizeof(s1));

 

    S s2 = {0};

 

    S s3;
    memset(&s3, 0, sizeof(s3));

 return 0;
}

컴파일러에서 최적화 옵션을 제거해 줍니다.

 

그리고 디스 어셈블리를 해보는겁니다.

 

결과는 아래에!

 

Release Mode 에서의 Disasembly code

    struct S{
        int a;
        int b;
        int c;
        int d;
        char e[20];
    };

    S s1;
    ZeroMemory(&s1, sizeof(s1));
004017F0  push        24h 
004017F2  push        0   
004017F4  lea         eax,[ebp-70h]
004017F7  push        eax 
004017F8  call        memset (401000h)
004017FD  add         esp,0Ch

    S s2 = {0};
00401800  mov         dword ptr [ebp-4Ch],0
00401807  xor         ecx,ecx
00401809  mov         dword ptr [ebp-48h],ecx
0040180C  mov         dword ptr [ebp-44h],ecx
0040180F  mov         dword ptr [ebp-40h],ecx
00401812  mov         dword ptr [ebp-3Ch],ecx
00401815  mov         dword ptr [ebp-38h],ecx
00401818  mov         dword ptr [ebp-34h],ecx
0040181B  mov         dword ptr [ebp-30h],ecx
0040181E  mov         dword ptr [ebp-2Ch],ecx

    S s3;
    memset(&s3, 0, sizeof(s3));
00401821  push        24h 
00401823  push        0   
00401825  lea         edx,[ebp-28h]
00401828  push        edx 
00401829  call        memset (401000h)
0040182E  add         esp,0Ch

 

뭐 딱 보면 아시겠죠? 워낙에 간단하잖아요.

ZeroMemory랑 memset은 같구요, (똑같이 인자를 스택에 넣고, memset의 주소를 콜하지요?)

 

={0} 은 좀 다른것 같죠?(단순히 0으로 채워 넣는겁니다. "xor ecx, ecx "에서 0을 만들잖아요)

 

ㅋ 근데 뭐 하는 일은 똑같습니다.

 

시간이 좀 있으시면, memset의 주소를 찾아가 보세요.(할 줄 아시면요~) 적잖이 긴 코드에 놀라실지도 모릅니다.

근데 사실,  최적화 옵션 켜고 컴파일하면 거기서 거기에요;

뭐 결론은, 전 웬만하면 ={0}으로 초기화 합니다. 편하잖아요. 가독성도 좋고. 

 

그리고, 더 재미있는게 있는데요!

 

구조체가 엄청 커지면 (쉽게 말하자면, memset을 호출하는게 기계어 코드가 더 짧아질 때 이겠죠) 지가 알아서 memset으로 바꿔줘요!

 

#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])


{
    struct S{
        char b[256];
    };

    S s1;
    ZeroMemory(&s1, sizeof(s1));

    S s2 = {0};

    S s3;
    memset(&s3, 0, sizeof(s3));

    return 0;
}

이건 직접 한번 디스 어셈블 해보세요!

'프로그래밍' 카테고리의 다른 글

Reliable udp  (0) 2011.08.18
1차원 배열 다수를 2차원 배열로  (0) 2011.08.18
[C특강] 배열을 사용한 효과적인 이중 링크드 리스트 구현  (0) 2011.07.23
C로 구현한 Queue  (0) 2011.07.18
구조체 동적 배열  (0) 2011.07.16