본문 바로가기
지난 학기들의 기록/C 기초

[C실습] 동적할당 예제 - realloc함수를 쓰지않고 배열의 크기 바꾸기

by 아메리카노와떡볶이 2020. 8. 22.
728x90
realloc함수를 쓰지않고 배열의 크기를 변경하기

realloc함수를 쓰지않고 malloc함수만을 이용해서 배열의 크기를 조건에 맞게 변경하는 프로그램을 작성하는 예제를 풀이해보겠습니다.

 

예제1.  초기배열의 크기를 넘어선 입력시 배열의 크기를 증가시켜라

 

#pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void size_add(int* s, int* arr);
int main() {
    //size가 5인 배열 생성
    int* Np;
    int i = 0;
    int size = 5;
    Np = malloc(sizeof(int) * size);

    scanf("%d", &Np[0]);
    if(Np[0]!=-1){
    for(i=1;;i++) {
        scanf("%d", &Np[i]);
        if (Np[i] == -1) break;
        if (i+1 >= size) { // 첫시행은 i=4일때
            size_add(&size, &Np);
        
        }
    }

    for (int k = 0; k <= i; k++) {
        printf(" %d", Np[k]);
    }
    }
   
    
    return 0;
}

void size_add(int* s, int** arr) {
    //newsize를 통해서 newarr을 만든다
    int newsize = *s + 3;
    int* temp;
    temp = malloc(sizeof(int) * newsize);
    
    //temp에 기존의 배열 원소들을 복사한다

    for (int i = 0; i < *s; i++) {

        temp[i] = (*arr)[i];
    }

    free(*arr);// 기존의 arr 메모리들을 해제한다.
    *arr = temp; //arr을 
    *s = newsize;
}

 

예제2. 배열의 크기를 입력받고 중간값에 해당하는 원소를 지운 배열을 재출력한다  

문제의 조건은 다음과 같습니다.

1. 배열의 초기 크기 N을 입력받습니다. ( N은 홀수만 입력가능하다고 가정합니다)

2. 정수 N개를 저장할수있는 메모리를 동적할당하고 이 메모리에 N개의 정수를 저장합니다.

3. N개의 정수에서 중간값에 해당하는 원소를 지웁니다.

4. 중간값이 지워진 배열을 재출력합니다.

 

크기 M( M=N-1 )의 새로운 배열을 만들어서 메모리를 동적할당하고, N의 최대 크기는 20이다.  

위의 코드를 변형하고, 마찬가지로 realloc은 사용할수없다.

 

입력예시

5

1 2 3 4 5

 

출력예시

1 2 4 5( 중간값 인덱스에 해당하는 3제거)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h>
 
void delete_middle(int* s, int** arr);
 
int main() {
    
    int N;
    scanf("%d"&N);
    // N개의 정수를 저장할수있는 메모리를 동적할당합니다.
    int* Np;
    Np = malloc(sizeof(int* N);
 
   
    for (int i = 0; i < N; i++) {
      scanf("%d",&Np[i]);
    }
 
    //배열의 크기N과 포인터Np의 주소를 매개변수로 넘깁니다
    delete_middle(&N, &Np);
   
    //중앙값이 삭제된 배열을 출력합니다.
    for (int i = 0; i < N; i++) {
        printf("%d ", Np[i]);
    }
 
    //메모리 해제
    free(Np);
    return 0;
}
 
void delete_middle(int* s, int** arr) {
    //중간값을 삭제하므로 배열의 크기가 1 줄어듭니다
    // 크기가 1 줄어든 배열을 새로 할당합니다.
    int newsize = *- 1;
    int* new_Np = malloc(sizeof(int* newsize);
    int newidx = 0;
 
    //메모리를 할당한 배열에 기존의 배열값을 복사합니다
    //이때 중간값은 제외합니다
    for (int k = 0; k <= *s; k++) {
 
        //newidx가 중앙값을 가리킬때
        // Np의 인덱스를 1증가시켜서 다음 값으로 넘긴다(삭제)
        //중간값을 건너뛴 다음값을 저장한다
        if (newidx == */ 2) {
            k++;
            new_Np[newidx] = (*arr)[k];
        }
        else {
            new_Np[newidx] = (*arr)[k];
        }
        newidx++;
    }
    //기존의 배열 메모리는 새로운 배열에 복사했으므로
    //해제하고 새로운 배열 new_Np를 가리키게 합니다
    free(*arr);
    *arr = new_Np;
    *= newsize;
}
cs

 

 

 

728x90

댓글