C언어 공부

C언어 기초 - 12. 문자열 배열과 문자열 포인터 (& C언어의 메모리 영역)

Client Side 2025. 8. 16. 18:51

1. 문자열 배열 (char arr[ ] = "Hello";)

  • %s : 문자열의 시작 주소를 인자로 받는다. 그 주소부터 차례로 문자를 읽어가다가 NULL 문자(\0)를 만나면 출력을 멈춘다.
  • 따옴표 사용 : 문자열일 때는 큰따옴표(" "), 문자 하나는 작은따옴표(' ')
  • char arr[ ] = "Hello" : 이렇게 선언하면 컴파일러가 자동으로 널 문자를 끝에 추가해서 총 6바이트 크기의 배열을 만들어준다.
  • 메모리할당 :  스택 메모리에 "Hello"를 저장할 수 있는 고정된 크기의 배열 공간이 만들어진다. 메모리에 arr이라는 이름의 공간이 생긴다.
  • 내용 변경 가능 여부 : 이 배열 안에 있는 문자들은 마음껏 바꿀 수 있다.

 

2. 문자열 포인터  (char *ptr = "Hello";)

  • 메모리 할당 : ptr 이라는 포인터 변수 자체는 스택 메모리에 생긴다. 그러나 ptr이 가리키는 "Hello"라는 문자열 리터럴은 사실살 프로그램 코드 안에 있는 상수(Constant)와 같다. 이 데이터는 보통 읽기 전용 메모리(Read-Only Memory)영역, 즉 데이터 영역이나 텍스트 영역 같은 곳에 저장된다.
  • 내용 변경 가능 여부 : ptr이라는 포인터 변수 자체는 다른 문자열을 가리키도록 바꿀 수 있다. (ptr = "Bye")  그러나 ptr이 지금 가리키고 있는 "Hello"의 내용을 직접 바꾸는 건 안된다. (*ptr = 'h') 왜냐하면 "Hello"는 그냥 '상수'라서 내용을 바꿀수 없도록 잠겨있기 때문이다.
char *str_ptr = "World"; // 'World'는 읽기 전용 메모리에 저장되고, str_ptr은 그 주소를 가리킴
// str_ptr[0] = 'G'; // 이렇게 변경 시도하면 런타임 오류 발생! (읽기 전용이라 변경 불가)
str_ptr = "Goodbye"; // str_ptr이 이제 'Goodbye'의 주소를 가리키게 변경하는 건 가능
printf("%s\n", str_ptr); // 출력: Goodbye

 

정리

  • 배열: 비어있는 (혹은 내용을 채울 수 있는) 공책 한 권을 통째로 받은 것과 같다. 거기엔 마음대로 글씨를 쓰고 지울 수 있다.
  • 포인터: 여기를 보라고 하는 쪽지 한 장을 받은 건데, 그 쪽지에는 이미 어떤 책의 페이지 주소가 적혀 있다. 사용자는 그 쪽지의 내용을 바꿔서 다른 책 페이지를 가리키게 할 순 있지만, 그 책 페이지의 내용을 직접 뜯어 고칠 수는 없다. 그 책은 원래부터 인쇄된 상태이기 때문이다!
  • 포인터 문자열: 포인터 변수 자체를 다른 주소로 재할당할 수 있지만, 포인터가 가리키는 '읽기 전용 문자열 리터럴'의 내용은 바꿀 수 없다.
  • 배열 문자열: 배열 안의 내용은 바꿀 수 있지만, **배열 이름 자체(시작 주소)**를 다른 주소로 재할당할 수는 없다.

 


C언어 메모리 영역

 

1. 코드(Code) 영역 또는 텍스트(Text) 영역

  • 저장되는 것 : 작성한 프로그램 코드가 기계어로 번역되어 여기에 저장된다. 우리가 아는 main()함수 및 다른 함수들의 명령어가 이 영역에 있다.
  • 특징 : 이 영역은 한번 로딩되면 변경되지 않는다. (읽기전용)  짜놓은 코드들을 실행 중에 막 바꾸면 안되기 때문. 그런 의미에서 텍스트 영역이라고도 부르며 주로 읽기 전용 속성을 가진다.

 

2. 데이터(Data)영역 (초기화된/초기화되지 않은)

  • 저장되는 것 : 주로 전역변수(global variable)나 정적변수(static variable)들이 저장된다.
    • 초기화된 데이터 영역 : 프로그램 시작과 동시에 특정 값으로 초기화된 변수들이 여기에 들어간다.
    • 초기화되지 않은 데이터 영역 : 값으로 초기화하지 않은 변수들은 이쪽에 들어가고, 컴파일러가 자동으로 0으로 초기화한다.

3. 힙(Heap) 영역

  • 저장되는 것 : 사용자가 원할 때 동적으로 할당하는 메모리가 저장된다.
  • 특징 : 프로그램 실행 중에 메모리 크기가 유동적으로 변할 수 있다.   필요한 만큼 메모리를 쓰고, 다 쓰면 free()함수로 메모리를 반환해줘야 한다.
  • 주의할 점 : 사용자가 직접 관리해야 하는 번거로움이 있지만, 필요한 만큼 할당해서 효율적으로 쓸 수 있다.

4. 스택(Stack) 영역

  • 저장되는 것 : 함수의 지역변수(local variable), 매개변수(parameter), 그리고 함수가 호출될 때 사용되는 정보(함수가 끝나고 돌아갈 주소 등)가 여기에 저장된다.
  • 특징 : 데이터가 스택처럼 쌓아고(push) 함수가 끝나면 사라진다. 'LIFO(Last-In, First-Out)방식이라서 가장 나중에 들어간 데이터가 가장 먼저 나오는 구조다. 함수가 호출될 때만다 스택이 위로 자라나고, 함수가 종료되면 스택이 다시 줄어드는 식이다.
  • 주의할 점 : 만약 재귀 함수처럼 함수 호출이 너무 많이 일어나면 스택 영역이 넘쳐버리는 스택 오버플로우가 발생할 수 있다.

특수한 함수

 

1. strlen 함수

  • 역할 : NULL문자를 제외한 문자열의 실제 길이를 반환해준다.
  • 사용법 예시 : strlen(문자열)
  • 헤더파일 : #include <string.h>

 

2. strcpy 함수

  • 역할 : 한 문자열의 내용을 다른 문자열로 통째로 복사한다.
  • 사용법 예시 : strcpy(목적지배열,원본문자열)
  • 헤더파일 :  #include <string.h>

3. strcat 함수

  • 역할 : 한 문자열 뒤에 다른 문자열을 덧붙여준다.
  • 사용법 예시 : strcat(기존문자열, 덧붙일문자열)
  • 헤더파일 #include <string.h>