Programming/C C++
연결 List를 다루는 부분에서 malloc()함수와 calloc()함수를 통해 어떻게 동적으로 Memory를 할당할 수 있을지에 대해 설명드린바 있습니다.

여기서는 다른 함수를 통하여 Memory를 복사하고 복사한 Memory를 초기화 하는 방법에 대해 알아보고자 합니다.

1. 확보된 Memory의 동적확장

C언어에서는 필요시에 이미 확보된 Memory영역을 더 확장할 수 있는 realloc()함수를 제공합니다. 이 함수를 이용하면 Program동작중에 기존 Memory영역을 더 크게 확보하는 것입니다.

#include <stdio.h>
#include <stdlib.h>

main()
{
  char s[5] = "hello";
  int i;
  char *p;
 
  for (i = 0; i < 5; i++)
    printf("%c\n", s[i]);
   
  p = (char *)realloc(s, 10);
 
  p[5] = 'k';
  p[6] = 'o';
  p[7] = 'r';
  p[8] = 'e';
  p[9] = 'a';
  p[10] = '\0';
 
  printf("%s\n", p);
 
  free(p);
}


이 Program은 먼저 s배열에 "hello"문자열을 담은 뒤 각 문자를 화면에 표시합니다. 이 후 p = (char *)relloc(s, 10); 구문을 통하여 선언된 s배열이 확보하고 있는 Memory영역을 10byte까지 확보하고 그 영역의 주소값을 Pointer로 반환하도록 하였습니다.(기존에는 배열 수가 5로 5Byte였습니다. 또한 (char *)로 형변환 해준것은 relloc()함수가 반환하는 Pointer형이 void이기 때문입니다.)

이렇게 확보된 Memory영역에 "korea"문자열을 각 문자별로 저장한 뒤 해당 Memory영역에 있는 Data를 문자열로 모두 출력하도록 합니다.(free()함수는 Pointer가 가리키고 있는 Memory영역을 해제합니다.)


위에서 realloc()함수 사용시 확보된 Memory영역을 korea로 초기화 해주고 있습니다.

이제 이러한 초기화 방법 대신에 기본적으로 제공하는 초기화 함수를 사용해 보겠습니다.(이 함수는 그렇게 유연한 기능을 제공하지 않는 탓에 자주 쓰이지는 않습니다.)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main()
{
  char s[5] = "hello";
  int i;
  char *p;
 
  for (i = 0; i < 5; i++)
    printf("%c\n", s[i]);
   
  p = (char *)realloc(s, 10);
 
  memset(p, 'h', 9);
  p[10] = '\0';
 
  printf("%s\n", p);
 
  free(p);
}


보시는 바와 같이 memset()함수를 통해 p에서 지정하고 있는 시작주소부터 9byte영역까지 문자 'k'로 초기화 해주고 있습니다.(memset(p, 'h', 9);)) 즉, 특정 문자를 지정한 Byte만큼 일괄적으로 설정하는 것입니다.

마지막배열에 '\0'으로 초기화 하여 문자열의 종료를 지정해 준다음 설정한 내용을 화면에 표시합니다.


참고 :
memset()함수는 string.h Header File에 선언되어 있습니다.

2. Memory영역 복사하기

필요한 Memory를 직접적으로 할당하는 방법도 괜찮지만 필요하다면 이미 할당된 Memory영역을 통째로 복사하여 기존의 Data까지 그대로 가져와 사용하는 방법도 있습니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main()
{
  char s[6];
  char *p;
 
  strcpy(s, "hello");
  printf("%s\n", s);
 
  p = (char *)calloc(5, 8);
 
  memcpy(p, s, 6);
 
  printf("%s\n", p);
 
  free(p);
}


s배열에 "hello"라는 문자열을 복사하고 Pointer p에는 8Byte 요소로 이루어진 8개의 배열공간을 확보하도록 하였습니다.

이렇게 Pointer p의 배열확보된 공간에 memcpy함수를 사용하여 p에 s배열의 Memory영역중 6Byte영역까지 복사하도록 합니다. 이때 해당 Memory의 Data까지 모두 복사되어 Pointer p와 문자배열 s는 동일한 크기와 값을 가지게 됩니다.


참고 :
복사한 내용을 외부의 다른 Pointer에 반환하는 형태가 아닌 자기 자신을 스스로 복사할 수도 있습니다.

#include <stdio.h>
#include <string.h>

main()
{
  char s[6];
 
  strcpy(s, "hello");
  printf("%s\n", s);
 
  memcpy(s, s+1, 3);
 
  printf("%s\n", s);
}


처음 s배열에 "hello"라는 문자열을 추가하고 memcpy함수를 통해 자기 자신(s 배열)을 복사하고 있습니다. 이때 복사할 원본은 s+1의 형태로 해당 주소를 1증가시킨 값부터 3Byte크기를 복사하도록 합니다.

결국 s의 시작주소 부터 1늘어난 주소값은 h이후의 e가 되고 e이후부터 3Byte크기 즉, ell을 s배열의 첫 시작부터 부터 다시 복사하는 것입니다.

0 0