인프런 커뮤니티 질문&답변

배정완님의 프로필 이미지
배정완

작성한 질문수

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

1-H

1-H 질문 있어요!

해결된 질문

작성

·

33

0

http://boj.kr/981e1180bdc04bcc847ce9ae1e0b9c5c

강의 듣기 전에 먼저 풀어봤는데 도저히 모르겠는 부분이 있어서 질문 드려요!

중간에 반복문을 for(int i = 1 ; i <= N-M; i++)가 아니라
for(int i = 0 ; i < N - M + 1; i++)로 했을 때 반복 횟수가 달라서(후자의 반복이 1회 더 많아서) 34%에서 틀렸는데,

후자의 반복문이 필요 이상으로 반복을 한다면 f_index가 인덱스 범위를 벗어나서 어떤 테스트 케이스에서든 문제가 생겼어야 할 거 같은데 왜 34%가 되서야 문제가 생겼을까요?
컴파일러에서 예외 발생이라도 떠야했을 거 같은데요..

답변 감사해요 강의 잘 보고 있어요!

 

답변 3

1

안녕하세요, 인프런 AI 인턴입니다. 정완님.

코드에서 반복문 조건을 변경했을 때의 오류에 대해 다음과 같은 유사 질문이 있습니다.

왜 틀렸는지 모르겠습니다 ㅠ

이 질문에서도 반복 횟수와 인덱스 범위에 대한 문제가 언급되고 있습니다. C/C++에서는 배열 인덱스가 범위를 벗어나도 컴파일러가 이를 자동으로 감지하지 않아, 일정 조건에서만 오류가 발생할 수 있습니다. 구체적으로, 예외 상황이 발생하지 않더라도 다른 메모리 영역에 접근함으로써 예상치 못한 결과가 나올 수 있습니다. 이는 중간 값 계산과도 연관되어 있을 수 있습니다.

한편, 이 문제를 해결하기 위해 다음과 같은 방안을 고려해 볼 수 있습니다:

  1. 빈번한 배열 인덱스 범위 오류 확인: 이 문제를 사전에 방지하기 위해 반복문 내의 인덱스가 배열의 범위를 벗어나지 않도록 주의가 필요합니다.
  2. 디버깅 및 예외 처리: 주어진 사례를 디버깅할 때, 배열 인덱스 범위를 검토하여 문제의 원인이 되는 부분을 파악할 수 있습니다.
  3. 명확한 반복 조건 설정: 반복문 조건을 수정할 때, 배열의 시작과 끝 인덱스를 정확히 확인하는 것이 중요합니다.

이를 통해 반목문 조건이 왜 예상한 대로 작동하지 않는지 더 명확히 이해하고 수정할 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

0

큰돌님의 프로필 이미지
큰돌
지식공유자

안녕하세요 정완님 ㅎㅎ

왜 34%가 되서야 문제가 생겼을까요?

-> 몇 퍼센트에 따라 문제가 생겼다고 그 부분에서 어떤 문제가 생겼는지는 파악하기가 어렵습니다. 다만, 어떤 문제가 있고 -> 틀렸다고 뜨는게 중요합니다.

 

코드에다 제가 디버깅코드를 추가해봤습니다.

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int N, M;
vector<int> sum;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> N >> M;
    int* arr = new int[N];
    for (int i = 0; i < N; i++) cin >> arr[i];

    int i_index = 0;
    int f_index = M;
    int tmp_sum = 0;

    // 첫 구간 합 계산
    for (int i = 0; i < M; i++) tmp_sum += arr[i];
    sum.push_back(tmp_sum);

    for (int i = 0; i <= N - M; i++) {  
        tmp_sum -= arr[i_index++];  // 구간에서 첫 번째 값 빼기
        tmp_sum += arr[f_index++];  // 구간에 새로운 값 더하기
        sum.push_back(tmp_sum);  // 새 구간 합 저장
        cout << i_index << " : " << f_index << '\n';
    }

    // 최댓값 출력
    cout << *max_element(sum.begin(), sum.end()) << endl;

    delete[] arr;
    return 0;
}

/*
1 : 3
2 : 4
3 : 5
4 : 6
5 : 7
6 : 8
7 : 9
8 : 10
9 : 11
*/

 

예를 들어 다음과 같은 입력을 넣었을 때 저렇게 뜨는데요. 10짜리 배열인데 9, 11 잘못된 인덱스를 참조하는 것을 볼 수 있습니다. -> 이 때문에 틀렸다고 뜨는 것 입니다.

10 2

3 -2 -4 -9 0 3 7 13 8 -310 2

 

컴파일러에서 예외 발생이라도 떠야했을 거 같은데요..
-> C++의 경우 arr[-1] 이런식으로 마이너스 인덱스도 참조가 가능합니다. 다만, 참조가 가능할뿐이지 이 코드는 UB를 발생할 수 있는 코드입니다. 이 때문에 이렇게 해서는 안됩니다.

즉, 잘못된 인덱스 참조 -> UB발생 -> 틀렸습니다. 로 이어진다고 보시면 됩니다.

*UB에 관한 내용은 교안에 있습니다.


 

또 질문 있으시면 언제든지 질문 부탁드립니다.

좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)

감사합니다.

강사 큰돌 올림.


 

 

 

0

배정완님의 프로필 이미지
배정완
질문자

컴파일러가 자동으로 감지하지 않는 경우도 있군요! 제대로 알아보지 않고 질문해서 죄송해요

배정완님의 프로필 이미지
배정완

작성한 질문수

질문하기