memset Show 변수 메모리 주소의 시작점으로부터 연속된 범위를 특정 값으로 지정하는 함수입니다. memset 함수 구조
s 가 가리키고 있는 메모리 영역 시작점으로부터 n 바이트를 c 로 채웁니다. memset 사용 이유 1. 수행 속도가 빠르기 때문입니다. 2. s 를 사용하기 전 내용을 비우는 작업을 해줍니다. 3. memcpy 사용 시 0x00 은 복사되지 않기 때문입니다. memset 으로 사전에 0x00 으로 할당해 두면, 더욱 안전하게 사용할 수 있습니다. memset 사용예제 일반 C 가 아닌 Embedded SQL 소스로 구성되어 있으며, 핵심 부분을 제외한 나머지 소스는 생략되어 있습니다. gSQL> CREATE TABLE T1 (C1 CHAR(10)); Table created. gSQL> INSERT INTO T1 VALUES ('GOLDILOCKS'); 1 row created. #include <stdio.h> #include <string.h> EXEC SQL BEGIN DECLARE SECTION; char sC1[10+1]; EXEC SQL END DECLARE SECTION; memset( sC1, 0x00, sizeof(sC1) ); // sC1 변수의 메모리 시작주소부터 sC1 변수의 크기만큼 0x00 으로 채웁니다. EXEC SQL SELECT C1 INTO :sC1 FROM T1; printf("sC1 = %s\n", sC1); ... sC1 = GOLDILOCKS 이번에는 memcpy() 라는 녀석에 대해서 알아보겠습니다. 아래는 MSDN에 명시되어 있는 함수 원형입니다. void *memcpy( void *dest, const void *src, size_t count ); 그럼, memcpy()의 기능, 특징 등을 한번 살펴 보도록 하죠. byte 단위의 메모리 복사memcpy()의 역할을 최대한 간결하게 설명하는 말이라 생각하고 적어보았습니다. memcpy()는 어떤 데이터든 상관없습니다. 왜냐면, 메모리의 값을 복사하는 것이니까요. 'A'가 메모리에 저장된 것과 65 라는 값이 메모리에 저장된 것을 구분할 수 있을까요? int value[3] = { 0x0, 0x0, 0x0 }; int i; 실행결과> NULL까지도 복사하는 능력문자열을 복사하는데에도 strpcy() 대신 memcpy()를 써야 하는 경우가 있습니다. strcpy()는 NULL 문자를 만날때까지의 값들을 복사하지만, memcpy()는 값은 상관없이 입력한 길이만큼 복사하게 되죠. 바로 그 차이 때문입니다. char string[100][100] = 이러한 데이터가 있다고 가정했을 때, 다른 곳으로 복사하려면 어떻게 해야할까요? 여러분이라면 어떻게 하시겠습니까? strcpy() 1번만에 복사가 가능할까요? 각 문자열은 NULL로 끝나기 때문에 아무리 노력해도 한번에 한개의 문자열밖에 복사할 수 없습니다. char dest[100][100]; 한번을 실행하더라도 strcpy()가 memcpy()보다 느립니다. 그런데 그걸 100배만큼 실행한다는 건 바람직하지 않겠지요. memcpy() 한줄로 끝나는 작업을 말이죠. 문자열인 경우에는 strcpy() 라는 함수가 있음에도 활용이 가능하다는 장점이 있습니다. 그러면 그외의 데이터는 두말할 것도 없이 써야겠지요. 메모리에 로드한 데이터들의 특정 부분을 가져온다던지 할때에 주력으로 쓰는 함수입니다. NULL 상관없이 복사하는 능력위의 'NULL까지도 복사하는 능력'과 조금 유사합니다만 다른 이야기를 하고자 합니다. 위에서는 NULL을 포함하는 문자열(혹은 문자열 집합)을 복사할때에는 strcpy()이 아닌 memcpy()를 써야한다고 했습니다. char str1[2][10] = { char ch; 실행결과> scanf()로 인덱스를 받아서, str1[1]의 'message' 중 해당하는 위치의 글자를 '*'로 바꾸기 위한 코드가 들어있습니다. 그런데 실수로 -1을 입력한 경우입니다. 그러면, str1[1][-1] 위치에 '*'를 넣게 되겠지요. 위의 경우에는 str[0]의 마지막 위치에 해당합니다. 즉, "This is a"의 끝을 알리는 NULL 위치입니다. before> after> 그래서, strcpy()를 하게 되면, "This is a"만 복사되는게 아니라 NULL을 만날때까지인 "This is a*message"가 str2로 복사되는 것입니다. memcpy()는 복사할 최대 길이를 지정할 수 있으므로 그런 위험이 없습니다. NULL이 없더라도 예상한 길이만큼만 복사되게 할 수 있죠. 다만, 위와 같은 경우를 대비해서 NULL을 입력해주는 코드를 추가하긴 해야 합니다. memcpy( str2, str1[0], sizeof(char)*10 ); 여기서 두가지 질문이 예상됩니다. 첫째는, strncpy() 함수를 이용하면 원하는 길이만큼 복사가 가능하다는 것입니다. 둘째는, strcpy()도 NULL을 강제로 넣도록 해주면 정상적인 문자열을 출력된다는 것입니다. memcpy()를 택할 수 밖에 없는 경우문자열이 아닌, 일반 데이터를 복사할때는 당연히 memcpy() 입니다. 이것은 진리죠. char string[100][100] = 이러한 데이터가 있다고 가정했을 때, 다른 곳으로 복사하려면 어떻게 해야할까요? 여러분이라면 어떻게 하시겠습니까? strcpy() 1번만에 복사가
가능할까요? 각 문자열은 NULL로 끝나기 때문에 아무리 노력해도 한번에 한개의 문자열밖에 복사할 수 없습니다. char dest[100][100];
어라? 컴파일 에러?strcpy()는 문자열을 복사하기 위한 함수라고 외우신 분들께서 memcpy()는 메모리값을 복사하기 때문에 값을 복사하는데 사용하실때 자주 실수하시는 것 같습니다. 'memcpy' : cannot convert parameter 1 from 'char' to 'void *' 보통 이러한 에러가 날텐데요. 파라메터들을 포인터로 넘기지 않아서 발생하는 것입니다. char str[] = "Hello, World"; strcpy( dest_str, src_str ); 주로 이렇게 사용하셨을 겁니다. int value = 100; memcpy( wallet, value, sizeof(value) ); 물론 아주 초보적인 실수입니다만, 이것이 구조체 형태로 넘어가면서 컴파일 에러를 찾는데 시간을 적잖게 허비하게 되기도 합니다. typedef struct { memcpy( blank, node, sizeof(node) ); 위의 구조체는 포인터 형태가 아니고 변수 형태이므로, 아래와 같이 '&'를 붙여서 주소값을 넘겨주도록 해야 합니다. memcpy( &blank, &node, sizeof(node) ); 프로그램이 좀 복잡해지면, 구조체를 #define으로 이름을 바꾸어 사용하고 하다보면 헷갈릴때가 종종 있어서, 의외로 헷갈릴 때가 있답니다. 어라? 이것밖에 복사가 안되네?특히 2 bytes 문자를 사용하는 경우에 이런 증상을 겪는 일이 자주 있습니다. #define LEN 10 전체 데이터의 크기는 20 bytes 입니다. 그러나, 이렇게 복사하게 되면 문자열의 절반 정도만 복사가 되겠지요? 이런 경우처럼 글자단위당 크기와 글자갯수를 혼동하는 경우에는 예상한 양보다 많거나 혹은 적게 복사되는 경우가 발생합니다. memcpy( dest, string, sizeof(MCHAR) * LEN ); 권장하는 방법은 위와 같이, 데이터단위의 크기를 sizeof()로 구한 다음에 길이만큼 곱해주는 방식입니다. 이렇게 코딩하시는 것이 차후에도 알아보기 편하고 정확하답니다. 마치면서...이쯤하면, memcpy()에 대해서 충분히 알아본 것 같은데요, 필요에 따라서, 차후에 업데이트 하도록 하겠습니다. |