본문 바로가기
C

백준 10818번 최대,최소 문제에서의 VLA와 동적할당 이슈

by KWONE 2024. 6. 20.

다음 문제를 보고 바로 다음과 같이 코드를 짜서 돌렸더니 오류가 발생했다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
    int N, X = 0;
    scanf("%d %d", &N, &X);
    int A[N];
    for (int i = 0; i < N; i++) {
        scanf("%d", &A[i]);
    }

    for (int i = 0; i < N; i++) {
        if (A[i] < X) {
            printf("%d ", A[i]);
        }
    }
   
    return 0;
}

그래서 오류를 확인해보니 배열 크기에 변수가 아닌 상수가 와야한다고 적혀있길래

챗지피티에게 문제를 복사하여 물어보았더니 이게 무슨 일인가,

나와 똑같이 답을 내준다. 그래서 혹시나하고 백준문제 제출을 하고 채점을 받아보니 

정답이라고 나오길래 의아해 하던참에 검색해본결과

컴파일러에 따라 VLA(가변 길이 배열)을 제공유무에 따라 오류가 생기거나 그렇지 않은것이었다.

따라서 내가 쓰는 비주얼 스튜디오에서는 VLA를 지원하지 않는 것을 확인하고

이를 해결하기 위해 동적 메모리 할당을 직접 해줘야 함을 알게되었다.

아래는 동적 메모리 할당을 통해 수정된 코드이다.

#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일

int main() {
    int N, v, count = 0;

    // 첫 번째 줄에서 정수의 개수 N 입력 받기
    scanf("%d", &N);

    // 배열의 크기를 N으로 동적 할당
    int *numbers = (int *)malloc(N * sizeof(int));
    if (numbers == NULL) {
        // 메모리 할당 실패 시 오류 메시지 출력 후 종료
        printf("Memory allocation failed\n");
        return 1;
    }

    // 두 번째 줄에서 N개의 정수 입력 받기
    for (int i = 0; i < N; i++) {
        scanf("%d", &numbers[i]);
    }

    // 세 번째 줄에서 찾으려고 하는 정수 v 입력 받기
    scanf("%d", &v);

    // numbers 배열에서 v의 개수를 셈
    for (int i = 0; i < N; i++) {
        if (numbers[i] == v) {
            count++;
        }
    }

    // 결과 출력
    printf("%d\n", count);

    // 동적 할당된 메모리 해제
    free(numbers);

    return 0;
}

이에 사용된 개념으로는


malloc(size_t size): 지정한 바이트 수 만큼의 메모리를 할당하고, 해당 메모리의 시작 주소를 반환합니다. 할당된 메모리는 초기화되지 않습니다.

free(void *ptr): 할당된 메모리를 해제합니다.

메인함수의 첫 문단을 보면 새롭게 배열의 크기를 정의 하기 위해 동적 메모리 할당이 이루어지는 것을 볼 수 있다.

int *numbers = (int *)malloc(N * sizeof(int)) 개의 정수를 저장할 배열을 동적으로 할당합니다. 할당된 메모리의 시작 주소가 numbers 포인터에 저장됩니다.


조금 자세히 설명하자면  int가 할당될수있는 저장공간을 N으로 만들어주고

에러를 방지하기위해 배열의 크기가 할당되지 않았을때(NULL) 오류 메시지를 출력하도록 하며

마지막으로 사용이 완료된 동적 할당 메모리를 해제 해준다. (free)

컴파일러에 따라 사용 방법을 달리하거나 직접 메모리 할당이 필요한 경우 동적 메모리 할당을 해줄 필요가 있다. 

다음은 VLA와 동적메모리 할당간의 차이점이다.

VLA:

  • 사용법이 간단하고 코드가 깔끔하다.
  • 스택 메모리를 사용하므로 메모리 관리가 자동으로 이루어진다.
  • 그러나 스택 메모리 크기가 제한되어 있어 큰 배열을 할당할 때는 위험할 수 있다.

동적 메모리 할당:

  • 더 많은 유연성과 제어를 제공한다.
  • 힙 메모리를 사용하므로 더 큰 메모리를 할당할 수 있다.
  • 하지만 할당한 메모리를 명시적으로 해제해야 하며, 메모리 누수 위험이 있다.
 
 

 

'C' 카테고리의 다른 글

날짜 구현  (0) 2024.06.23
동적 메모리 할당  (0) 2024.06.21
포인터 연습 예제2  (0) 2024.06.04
포인터 연습 예제1  (0) 2024.06.03
문자열 배열 연습 4  (0) 2024.05.29