
동적 할당은 입력 데이터의 크기가 미리 정해져 있지 않은 상황에서 매우 유용하게 활용할 수 있습니다.
static) 변수가 저장되는 영역malloc, calloc, realloc)free로 회수해야 함!!char temp[80]; // 입력 문자열을 임시로 저장
char *str[4]; // char* 포인터 4개로 구성된 배열
for (int i = 0; i < 4; i++){
printf("문자열 입력: ");
// temp 배열에 문자열 저장
fgets(temp, sizeof(temp), stdin);
// 입력 문자열에서 첫 "\n"의 위치를 찾아, 널문자로 바꿈
temp[strcspn(temp, "\n")] = '\0';
// 문자열의 길이만큼 메모리 할당
// 널 문자 고려해 1 추가
str[i] = (char *)malloc(strlen(temp) + 1);
strcpy(str[i], temp);
}
// 문자열 출력
for (int i = 0; i < 4; i++){
printf("%s ", str[i]);
}
// 동적 할당한 메모리 해제
for (int i = 0; i < 4; i++) {
free(str[i]);
}
// [입력]
// 문자열 입력: I love
// 문자열 입력: coffee
// 문자열 입력: and
// 문자열 입력: tea
// [출력]
// I love coffee and tea

80 크기의 char 배열 temp에 입력받음strlen(temp) + 1 길이에 맞게 동적 할당 후, strcpy로 시작 주소를 포인터 배열 str의 원소에 저장strlen(temp)은 배열 temp에 저장된 문자열의 길이를 반환1을 더해준 이유: 널 문자를 포함해야 함int arr[N], int arr[N][M]과 같은 식으로int arr[N] = {0} 식으로 초기화 불가능, 직접 값을 대입해야 함free()로 할당 해제를 할 필요도 없음#include <stdio.h>
int main(void){
int N, M;
printf("행의 수: ");
scanf("%d", &N);
printf("열의 수: ");
scanf("%d", &M);
int arr[N][M];
// 가변 길이 배열은 초기화할 수 없고, 선언만 가능
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j++){
arr[i][j] = N * i + j;
}
}
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j++){
printf("%4d", arr[i][j]);
}
printf("\n");
}
}
// [입력]
// 행의 수: 4
// 열의 수: 5
// 출력
// 0 1 2 3 4
// 4 5 6 7 8
// 8 9 10 11 12
// 12 13 14 15 16
free 해제시켜주지 않아도 되는 장점이 있지만4행 5열의 행렬 값을 저장할 2차원 배열을 동적 할당하고, 작성한 값을 반환하는 코드를 작성하세요.

malloc(sizeof(int) * 5)로 할당해야겠지?int *형으로 형 변환해야겠지?int *만 알고 있으면 됨malloc(sizeof(int *) * 4)로 할당해야겠지?int **형이겠지?int **형 포인터가 필요함#include <stdio.h>
#include <stdlib.h>
int main(void){
// 이중 포인터 p 선언
// int * 원소 4개의 배열을 저장할 수 있는 공간 마련
// 메모리 크기는 4 * sizeof(int *)
int **p = malloc(sizeof(int *) * 4);
// 널포인터 여부 체크
if (p == NULL) exit(1);
for (int i = 0; i < 4; i++){
// int 원소 5개의 배열을 저장할 수 잇는 공간 마련
// 메모리 크기는 5 * sizeof(int)
p[i] = malloc(sizeof(int) * 5);
// 널포인터 여부 체크
if (p[i] == NULL) exit(1);
for (int j = 0; j < 5; j++){
int num = 5 * i + j;
p[i][j] = num;
}
}
// 출력하기
for (int i = 0; i < 4; i++){
for (int j = 0; j < 5; j++){
printf("%3d", p[i][j]);
}
printf("\n");
}
// 반환하기
for (int i = 0; i < 4; i++){
free(p[i]);
}
free(p);
}
// [출력]
// 0 1 2 3 4
// 5 6 7 8 9
// 10 11 12 13 14
// 15 16 17 18 19
4, 5만 해당 값으로 바꿔주면 문제없음키보드로 양수를 입력한 후에 입력한 수 이전 수까지 모든 소수를 출력합니다.
2부터 한 줄에 5개씩 출력하며, 소수가 아닌 수는 X를 출력합니다.
입력한 수에 따라 적절한 크기의 배열을 동적 할당해 사용합니다.
target으로 둘 때, target개의 int 원소를 저장할 공간 동적 할당 후 포인터 p에 주소 대입p[i]가 0이면 소수이고, p[i]가 1이면 소수가 아니라고 해석calloc으로 모든 값을 0으로 초기화#include <stdio.h>
#include <stdlib.h>
#include <math.h> // sqrt 함수
int main(void){
int target;
printf("양수 입력 : ");
scanf("%d", &target);
// (target)개의 원소를 저장할 공간 동적 할당 후, 0으로 초기화
// p[i] == 0: 소수
// p[i] == 1: 소수 아님
int *p = (int *)calloc(target, sizeof(int));
// 널 포인터인지 확인
if (p == NULL) exit(1);
// 에라토스테네스의 체
// 제곱근을 구하는 sqrt는 double 타입을 받고 반환. 이에 맞게 형변환
int final_num = (int)sqrt((double)target);
for (int i = 2; i <= final_num; i++){
// 지금 수가 소수인 경우
if (p[i] == 0){
// 지금 수의 배수는 소수가 아님
for (int j = i * i; j < target; j += i){
p[j] = 1;
}
}
}
// 2부터 시작해서 소수면 수를, 소수가 아니면 X를 출력
int count = 0;
for (int i = 2; i < target; i++){
if (p[i] == 0){
printf("%4d", i);
} else {
printf("%4c", 'X');
}
count++;
if (count % 5 == 0){
printf("\n");
}
}
// 메모리 반환
free(p);
}
// [입력]
// 양수 입력 : 30
// [출력]
// 2 3 X 5 X
// 7 X X X 11
// X 13 X X X
// 17 X 19 X X
// X 23 X X X
// X X 29

malloc, calloc을 사용하면 편한 이유?target에 따라서 소수인지 아닌지 판별해야 하는 수의 수가 달라지기 때문입니다.malloc을 사용하면 입력받은 target 값에 따라 필요한 만큼 공간을 할당할 수 있겠죠.