security
CHAPTER 86 / 96
읽기 약 2분
FUNCTION
C 최소 문법: 배열과 문자열
핵심 개념
배열·문자열·strlen/strcpy — C 문자열의 \0 종료. 버퍼 개념 도입.
본문
배열 선언
#include <stdio.h>
int main(void) {
// 배열 선언 + 초기화
int nums[5] = {1, 2, 3, 4, 5};
char letters[3] = {'A', 'B', 'C'};
// 인덱스 접근
printf("%d\n", nums[0]); // 1
printf("%d\n", nums[4]); // 5
// ⚠️ 범위 외 접근 — 정의되지 않은 동작
// printf("%d\n", nums[5]); // 쓰레기 값 또는 크래시
// 크기
printf("size: %zu\n", sizeof(nums)); // 20 (4*5)
printf("len: %zu\n", sizeof(nums) / sizeof(nums[0])); // 5
return 0;
}문자열 — \0 종료가 핵심
#include <stdio.h>
#include <string.h>
int main(void) {
// 문자열 = char 배열 + \0 (null 문자)
char str1[] = "Hello"; // 자동으로 \0 추가 (6바이트)
char str2[6] = "World"; // 명시적 (W,o,r,l,d,\0)
char str3[] = {'H','i','\0'}; // 직접 \0 추가
printf("%s\n", str1); // Hello
printf("size: %zu\n", sizeof(str1)); // 6 (Hello + \0)
printf("len: %zu\n", strlen(str1)); // 5 (\0 제외)
return 0;
}strcpy의 위험성
#include <stdio.h>
#include <string.h>
int main(void) {
// ❌ 위험: 대상 크기 검사 없음
char dest[5];
char src[] = "Hello, World!"; // 13 + \0
strcpy(dest, src); // ⚠️ 버퍼 오버플로우
printf("%s\n", dest); // 정의되지 않은 동작
return 0;
}// ✅ 안전: strncpy + 명시적 \0
#include <stdio.h>
#include <string.h>
int main(void) {
char dest[5];
char src[] = "Hello, World!";
strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0'; // 명시적 종료
printf("%s\n", dest); // Hell (4 + \0)
return 0;
}더 안전한 대안
// 1. snprintf — 모든 플랫폼
#include <stdio.h>
int main(void) {
char dest[5];
snprintf(dest, sizeof(dest), "%s", "Hello, World!");
// 자동 \0 종료 + 잘림 처리
printf("%s\n", dest); // Hell
return 0;
}
// 2. strlcpy — BSD/macOS (Linux는 libbsd 필요)
// strlcpy(dest, src, sizeof(dest));
// 자동 \0 종료 + 잘림 시 원본 길이 반환
// 3. C11 strcpy_s (Annex K, 선택적 구현)
// errno_t strcpy_s(char *dest, rsize_t destsz, const char *src);문자열 비교
#include <stdio.h>
#include <string.h>
int main(void) {
char a[] = "apple";
char b[] = "apple";
char c[] = "banana";
// ❌ 잘못 — 포인터 주소 비교
printf("a == b: %d\n", a == b); // 0 (다른 주소)
// ✅ 올바름 — 내용 비교
printf("strcmp(a, b): %d\n", strcmp(a, b)); // 0 (같음)
printf("strcmp(a, c): %d\n", strcmp(a, c)); // 음수 (a < c)
return 0;
}버퍼 = 고정 크기 메모리 영역
// 버퍼 = 임시 데이터 저장 공간
char input_buffer[256]; // 256바이트 버퍼
char output_buffer[1024]; // 1KB 버퍼
// ⚠️ 버퍼는 고정 크기 — 입력이 더 크면 오버플로우
// 다음 챕터: 포인터로 메모리 직접 다루기다음 챕터
CH.3 "포인터 기초" — 메모리 주소의 세계 진입.
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 C 코드의 strcpy/sprintf/gets 같은 위험 함수 사용 위치를 모두 찾고 안전한 대체를 적용해줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
CERT C Coding Standard의 문자열 관련 규칙 Top 10과 위반 사례를 비교 분석해줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 C 프로젝트 전체에서 버퍼 관련 잠재적 취약점을 자동 스캔하고 우선순위 리포트를 만들어줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 OWASP Buffer Overflow 통계와 실제 CVE 발생 빈도를 솔직히 알려줘.
⭐ 이것만 기억하세요
C 최소 문법: 배열과 문자열은 이 3가지만 확실히 잡으세요
1.C 문자열은 \0 종료 + char 배열 — strlen은 \0 전까지, sizeof는 전체 바이트
2.strcpy는 대상 크기 검사 없어 위험 — 항상 strncpy/snprintf + 명시적 \0
3.다음 챕터 CH.3에서 포인터 기초 — 메모리 주소를 직접 다루는 핵심
공유하기
진행도 86 / 96