이미 저장되어 있는 문자열을 다른 곳에 복사하려면 어떻게 해야 할까? 문자열을 복사하는 방법과 주의사항을 알아보자.
잘못된 문자열 복사
문자열을 복사하기 위해 아래 코드를 실행해보자.
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
int main(void)
{
string s = get_string("s: ");
string t = s;
t[0] = toupper(t[0]);
printf("s: %s\n", s);
printf("t: %s\n", t);
}
입력: emma
출력:
s: Emma
t: Emma
s 변수에는 'emma'라는 문자열이 아닌 그 문자열이 있는 메모리 주소가 저장된다. string s는 char *s와 동일한 의미이므로, t도 s와 동일한 주소를 가리킨다.
그렇기 때문에 t만 수정했는데 s도 함께 바뀐 것이다.
메모리 상황:
주소 0x100: e m m a \0
↑
s, t 둘 다 가리킴
t[0] = 'E' 수정
↓
주소 0x100: E m m a \0
↑
s, t 둘 다 가리킴
올바른 문자열 복사
두 문자열을 실제로 메모리상에서 복사하려면 메모리 할당 함수를 사용해야 한다.
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char *s = get_string("s: ");
char *t = malloc(strlen(s) + 1);
for (int i = 0, n = strlen(s); i < n + 1; i++)
{
t[i] = s[i];
}
t[0] = toupper(t[0]);
printf("s: %s\n", s);
printf("t: %s\n", t);
}
입력: emma
출력:
s: emma
t: Emma
이제 s와 t가 독립적으로 존재한다.
코드 분석
1. 메모리 할당
char *t = malloc(strlen(s) + 1);
malloc: 메모리 할당 함수strlen(s) + 1: 문자열 길이 + 널 종단 문자(\0)
2. 문자 복사
for (int i = 0, n = strlen(s); i < n + 1; i++)
{
t[i] = s[i];
}
s의 각 문자를t로 하나씩 복사i < n + 1: 널 종단 문자까지 복사
메모리 상황
주소 0x100: e m m a \0 ← s가 가리킴
주소 0x200: e m m a \0 ← t가 가리킴 (새로 할당)
t[0] = 'E' 수정
↓
주소 0x100: e m m a \0 ← s (변화 없음)
주소 0x200: E m m a \0 ← t (수정됨)
strcpy 함수 사용
C 표준 라이브러리의 strcpy 함수를 사용하면 더 간단하다.
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char *s = get_string("s: ");
char *t = malloc(strlen(s) + 1);
strcpy(t, s);
t[0] = toupper(t[0]);
printf("s: %s\n", s);
printf("t: %s\n", t);
}
strcpy(t, s)는 s의 모든 문자를 t로 복사한다.
메모리 해제
malloc으로 할당한 메모리는 사용 후 반드시 해제해야 한다.
free(t);
전체 코드
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char *s = get_string("s: ");
char *t = malloc(strlen(s) + 1);
if (t == NULL)
{
return 1; // 메모리 할당 실패
}
strcpy(t, s);
t[0] = toupper(t[0]);
printf("s: %s\n", s);
printf("t: %s\n", t);
free(t); // 메모리 해제
return 0;
}
복사 방법 비교
| 방법 | 코드 | 결과 |
|---|---|---|
| 주소만 복사 | t = s |
❌ 같은 메모리 가리킴 |
| 직접 복사 | for + malloc |
✅ 독립적인 복사본 |
| strcpy 사용 | strcpy(t, s) |
✅ 독립적인 복사본 |
연습 문제
Q. 메모리 할당 없이 문자열의 주소만 복사했을 때는 어떤 문제가 생길까?
값이 복사되지 않고 같은 주소만 가리키게 되어 의도와 다르게 원본이 훼손될 수 있다.
- 포인터 복사 = 주소만 복사 (얕은 복사)
- 문자열 복사 = 새 메모리 할당 + 내용 복사 (깊은 복사)
'TIL' 카테고리의 다른 글
| [CS50] 메모리 - 메모리 교환, 스택, 힙 (0) | 2025.11.08 |
|---|---|
| [CS50] 메모리 - 메모리 할당과 해제 (0) | 2025.11.08 |
| [CS50] 메모리 - 문자열 비교 (0) | 2025.11.07 |
| [CS50] 메모리 - 문자열과 메모리 (0) | 2025.11.07 |
| [CS50] 메모리 - 포인터 (0) | 2025.11.07 |
