#include <stdio.h>
int main(void){
char a1[10] = "Hello1";
char a2[] = "Hello2";
char* str2 = "Hello3";
printf("%s %s %s\n", a1, a2, str2);
return 0;
}
위에서 char* str2 = "Hello3"; 이 '문자열 포인터'이다. char* 형 인데도 r value 로 문자열이 직접 들어간다는 점이 특이하니 기억하자!
또, format specifier 로 %c 를 써야 하는지, 콤마 뒤 부분에 str2 인지 *str2 인지 헷갈릴 수 있는데, %s 이고 *없이 str2로 써야 한다!
C 에서 동적 메모리 할당을 사용하려면 malloc 함수를 사용한다.
포인터 = malloc(크기);
의 형식이다.
#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
int main()
{
int num1 = 20; // int형 변수 선언
int *numPtr1; // int형 포인터 선언
numPtr1 = &num1; // num1의 메모리 주소를 구하여 numPtr에 할당
int *numPtr2; // int형 포인터 선언
numPtr2 = malloc(sizeof(int)); // int의 크기 4바이트만큼 동적 메모리 할당
printf("%p\n", numPtr1); // 006BFA60: 변수 num1의 메모리 주소 출력
// 컴퓨터마다, 실행할 때마다 달라짐
printf("%p\n", numPtr2); // 009659F0: 새로 할당된 메모리의 주소 출력
// 컴퓨터마다, 실행할 때마다 달라짐
free(numPtr2); // 동적으로 할당한 메모리 해제
return 0;
//source: https://dojang.io/mod/page/view.php?id=285
}
malloc 함수는 주솟값을 반환하는데, 일반으로 포인터에 주솟값을 할당하면 컴퓨터의 stack에 해당하는 영역의 주솟값을 주지만
malloc 을 이용하면 heap에 해당하는 영역의 주솟값을 준다.
그리고 이렇게 heap 영역으로 할당해준 메모리는 사용이 모두 끝난 후 free 함수를 통해 풀어줘야 한다는 큰 차이점이 있다. (선택이 아니라 필수다.)
마치 파이썬처럼 C, C++에서 프로그래밍을 이런 식으로 하면 답이 없다.
void TestFuntion(int n){
int fixed_size_array[20];
int variable_size_array[n]; //!!error!!
for (int i=0; i<n; ++i) {
cout << fixed_size_array[i] << ", " << variable_size_array[i];
}
}
malloc함수의 반환형은 void형이므로, 반환값을 변형시키지 않으면 메모리 공간에 접근이 불가능하다.
따라서 형 변환자를 이용해야 한다.
int * ptr = (int *)malloc(sizeof(int));
위에서 언급했던 "실행 도중 크기가 변화하는 array 를 C에서 어떻게 만들까?" 라는 질문에 대한 답이 malloc 함수에 있다.
#include <stdio.h>
#include <stdlib.h>
void TestFunction(int n) {
int* variable_size_array = (int*) malloc(sizeof(int) * n);
for (int i = 0; i < n; ++i) {
variable_size_array[i] = i;
}
free(variable_size_array);
}
int main() {
TestFunction(3);
return 0;
}
또한, malloc 을 통해 heap 의 메모리를 할당받은 포인터의 이름을 free 의 인자로 넘겨줘야 한다는 것도 잊지 말아야 한다.
이중 포인터로 malloc 을 할 수도 있다.
이중이기 때문에 이차원 배열과 비슷하게 생성될거라고 유추할 수 있겠다.
예시 코드를 하나 가져오겠다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char **p_playlist;
int i;
int play_cnt = 5;
p_playlist = (char**) malloc(sizeof(char*) * play_cnt);
for(i=0; i<play_cnt; i++) {
p_playlist[i] = (char*)malloc(sizeof(char)*256);
}
strcpy(p_playlist[0], "TEST playlist 0");
strcpy(p_playlist[1], "TEST playlist 1");
strcpy(p_playlist[2], "TEST playlist 2");
strcpy(p_playlist[3], "TEST playlist 3");
strcpy(p_playlist[4], "TEST playlist 4");
for(i=0; i<play_cnt; i++) {
printf("playlist [ %d ] : %s\n", i, p_playlist[i]);
free(p_playlist[i]);
}
free(p_playlist);
return 0;
}
이렇게 하면 크기가 {sizeof(char*) * play_cnt} * {sizeof(char) * 256} 인 포인터 배열이 생성될 것이다.