얕은복사
실제 데이터가 아니라 주소를 복사하는 것을 얕은복사라 한다.
#include <stdio.h>
typedef struct name{
char* lastname;
char* firstname;
} name_t;
void main()
{
char fistname[] = "Lulu";
char lastname[] = "Lee";
name_t name;
name_t clone;
name.lastname = lastname;
name.firstname = fistname;
clone = name;
name.lastname[0] = 'N';
printf("origin: %s %s\n", name.firstname, name.lastname);
printf("clone: %s %s\n", clone.firstname, clone.lastname);
}
// 출력값
// origin: Lulu Nee
// clone: Lulu Nee
골때리게도 name의 lastname만 N으로 바꿨는데 clone의 lastname까지 변경됐다.
clone = name의 실행이 바로 얕은복사 이기 때문이다.
name의 구조체에서 char* lastname은 포인터다. 포인터는 주소를 변수로 저장하는 놈이다.
그러므로 구조체 char* lastname은 main함수의 lastname 배열의 주소를 값으로 가지고 있다.
따라서 mian 함수에서 name.lastname[0] ='N'을 하게되면 main 함수의 lastname의 원본 L이 N으로 변경되고 그 주소를 참조하는 변수 clone, name은 둘다 변경 된 것처럼 된다.
얕은복사 메모리
name과 clone의 lastname 값을 보면 105번 주소를 저장하고 있고 105번에는 L이 저장돼있다.
name.lastname[0]은 원본을 바꾼다. 나머지 포인터들은 그냥 가르키는 값을 참조 할 뿐이니 둘다 바뀐것 처럼 느껴진다.
깊은복사
별도의 메모리 공간에 실제 데이터를 복사한다.
//typedef struct name{
// char* lastname;
// char* firstname;
//} name_t;
typedef struct name{
char lastname[64];
char firstname[64];
} name_t;
void main()
{
name_t name = {"Lulu", "Lee"};
name_t clone;
clone = name;
name.lastname[0] = 'N';
printf("origin: %s %s\n", name.firstname, name.lastname);
printf("clone: %s %s\n", clone.firstname, clone.lastname);
}
// 출력값
// origin: Lee Nulu
// clone: Lee Lulu
얕은복사 코드를 위의 코드로 변경하면 origin 즉 원본의 값만 변경되고 clone 값은 유지된다. 왜냐? 별도의 메모리 공간을 확보한 뒤 거기에 값을 복사했기 때문이다.
'C' 카테고리의 다른 글
C언어 void* (0) | 2019.12.20 |
---|---|
C 언어 변수에 함수 할당 (0) | 2019.12.20 |
C언어 구조체 (0) | 2019.12.18 |
C언어 포인터 배열 (0) | 2019.12.13 |
C 포인터 const (0) | 2019.12.12 |