포인터 배열

개념

  • 포인터를 저장하는 배열
  • 포인터가 여러 개 사용될 때, 이를 한 번에 담는 포인터 배열을 활용할 수 있다.
  • 주로 문자열 배열 처리에 활용된다.
  • 한 행의 길이가 일정하지 않을 때, 포인터 배열이 2차원 배열에 비해 효율적인 경우가 많다.

2차원 배열보다 포인터 배열이 효율적인 이유
2차원 배열은 n x m 의 고정된 크기 형태를 가질 수 있다.
이는 반대로 말하면, 각 배열을 정보로 가득 채우지 못하면, 남는 잉여 메모리가 발생할 수 있다는 것이다.
반면 포인터를 배열에 담게 되면, 각 정보가 필요한 만큼의 메모리만 사용할 수 있는 것이다.
하지만, 포인터 자체도 메모리를 사용하므로(8바이트) 항상 2차원 배열보다 효율적이라는 것은 아니다.

도식으로 이해하기

  • 2차원 배열
1
2
3
4
5
6
7
8
9
10
11
char arr[3][10];

메모리 구조
┌──────────┬──────────┬──────────┐
│ H e l l o \0 □ □ □ │
├──────────┼──────────┼──────────┤
│ W o r l d \0 □ □ □ │
├──────────┼──────────┼──────────┤
│ A \0 □ □ □ □ □ □ □ │
└──────────┴──────────┴──────────┘
// 모든 행이 10일 경우 -> 낭비되는 메모리 존재
  • 포인터 배열
1
2
3
4
5
6
7
8
9
char *arr[3];

arr (포인터 배열)
┌───────┬───────┬───────┐
│  * ───┼──▶ H e l l o \0
│  * ───┼──▶ W o r l d \0
│  * ───┼──▶ A \0
└───────┴───────┴───────┘
// 포인터 배열은 필요한 만큼만 사용하므로 효율적임

예시

2차원 배열의 사용

1
2
3
4
char str[3][20] = {"cat", "computer", "123456789"};
for (int i = 0; i < 3; i++) {
    printf("%-10s  | size : %ld\n", str[i], sizeof(str[i]));
}
1
2
3
4
5
6
# 출력
cat         | size : 20 
computer    | size : 20
123456789   | size : 20
# 총합 60
# cat 은 3자만 저장하면 되지만, 20개의 공간을 할당받았음 --> 비효율

포인터 배열을 사용

1
2
3
4
5
6
7
char *str[3] = {"cat", "computer", "123456789"};
for (int i = 0; i < 3; i++) {
    printf("%-10s  | size : %ld\n", str[i], sizeof(str[i]));
}
for (int i = 0; i <3; i++) {
    printf("%-10s  | size : %ld\n", str[i], strlen(str[i]));
}
1
2
3
4
5
6
7
8
# 출력
cat         | size : 8
computer    | size : 8
123456789   | size : 8
cat         | size : 3
computer    | size : 8
123456789   | size : 9
# 총합 48
  • 포인터 자체는 8바이트 크기를 가짐
  • 거기에 각 문자열의 크기만큼이 저장공간으로 필요

Reference

C 프로그래밍 (김형근, 곽덕훈, 정재화 공저)
C 프로그래밍 강의 (방송통신대 - 이병래)

Comments