Wednesday, April 30, 2008

Manipulating Memory

메모리를 다루는 여러 함수들을 살짝 다루고 넘어가자.

특정 값으로 초기화 는 memset을 사용한다. BSD에서는 bzero를 사용하기도 한다. malloc 한 후 memset 하는 짓... 하지 말고 그냥 calloc() 을 사용하는 것이 함수 호출도 줄이고, 코드도 짧아지고, 성능도 향상된다.

#include <string.h>
void * memset(void *s, int c, size_t n);

메모리 비교하기 는 memcmp를 쓰면된다. 마찬가지로 BSD에서는 bcmp를 지원한다. 주의할 것은 구조체의 경우 패딩값으로 쓰레기 값들이 들어갈 수 있어서 구조체의 비교를 memcmp로 하면 안된다(같아도 다른 값이 나올 수 있기 때문이다). 구조체는 해당 값들을 일일이, 직접 비교해줘야 한다.

#include <string.h>
int memcmp (const void *s1, const void *s2, size_t n);

메모리 복사(이동) 은 memmove 와 좀더 친근한 memcpy가 있다. 둘간에 차이가 있는데, memmove는 src, dst 공간의 overlap을 허용한다는 것과, memcpy는 overlap되는 경우 동작이 unknown이라는 거다. overlap된 메모리의 데이터를 변환할거라면 구지 이런 함수들 쓰지 말고 포인터로 직접 해줘야 겠다.

#include <string.h>
void * memmove(void * dst, void * src, size_t n);
void * memcpy(void * dst, void * src, size_t n);

그외에도 특정 문자가 나타날 때까지만 복사하는 memccpy(*dst, *src, size) 가 있고, 특정 바이트를 찾는 memchr 가 있다(memrchr은 GNU에서 제공하는 것인데, 뒤에서부터 꺼꾸로 찾는다).

#include <string.h>
void * memchr(const void *s, int c, size_t n);
#define _GNU_SOURCE
void * memrchr(/* same as above*/);

그리고 haystack에서 needle을 찾는 함수 (일종의 strstr...?) memmem도 있다.

#define _GNU_SOURCE
#include <string.h>
void * memmem(const void *haystack,
size_t hatstacklen,
const void *needle,
size_t needlelen);

조금 희한한 함수로, 무조건 '42'와 XOR 해서 넘겨주는 memfrob이 있는데, 두번 XOR하면 원래 것이 나오므로, 임시로 데이터를 희끄므리 ... 하게 하고 싶을 때 쓴다(아마도 encryption이 중시되지 않을 때 만든 것인듯).

#define _GNU_SOURCE
#include <string.h>
void * memfrob(void *s, size_t n);
memfrob(memfrob(text, len), len); // same!

No comments:

Post a Comment