boj 1389번 코드를 작성해보며 만나게된 zsh: bus error 와 지속적으로 발견되고 있는 내 '그래프 문제' 해결 코드에서의 문제점 보완 방안.
#include <bits/stdc++.h>
using namespace std;

vector<int> adj[105];
int dist[105];//각 vertex까지의 거리를 기록할 배열
int score[105];//각각의 거리의 합을 입력할 배열
int tot_dist;
int n,m;

int bfs(int st){
    tot_dist=0;
    fill(dist,dist+105,-1);
    queue<int> q;
    dist[st]=0;
    q.push(st);
    while(!q.empty()){
        int cur=q.front(); q.pop();
        for(auto nxt: adj[cur]){
            if(dist[nxt]!=-1) continue;
            dist[nxt]=dist[cur]+1;
            q.push(nxt);
        }
    }
    for(int i=1; i<=n; i++){
        tot_dist+=dist[i];
    }
    return tot_dist;
}

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

    cin>>n>>m;
    while(n--){ /*아래에 언급하겠지만 이렇게 작성하면 안된다. 혹시 이 코드를 참고하시는 분은 꼭 이 부분을
    수정하길 바란다. */
        int u,  v;
        cin>>u>>v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    
    for(int i=1; i<=n; i++){
        score[i]=bfs(i);
    }
    int min_kevin=*min_element(score+1,score+1+n);
    for(int i=1; i<=n; i++){
        if(score[i]==min_kevin) {
            cout<<i;
            return 0;
        }
    }
}

처음에 위와 같은 코드를 제출했는데, 내 맥북에서 코드를 돌려보았을때 예제입력을 했을시에 계속해서 

zsh: bus error 라는 출력을 받게 되었다. 

bus error의 경우 잘못된 메모리 접근에 기인하는 오류였던것 같은데 정확하게 기억이 나지 않아서 관련되어서 한번 검색해보았다. 

 

#include <bits/stdc++.h>
using namespace std;

vector<int> adj[105];
int dist[105];
int score[105];
int tot_dist;
int n, m;

int bfs(int st) {
    tot_dist = 0;
    fill(dist, dist + 105, -1);
    queue<int> q;
    dist[st] = 0;
    q.push(st);
    while (!q.empty()) {
        int cur = q.front();
        q.pop();
        for (auto nxt : adj[cur]) {
            if (dist[nxt] != -1) continue;
            dist[nxt] = dist[cur] + 1;
            q.push(nxt);
        }
    }
    for (int i = 1; i <= n; i++) {
        tot_dist += dist[i];
    }
    return tot_dist;
}

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

    cin >> n >> m;
    int originalN = n; // 입력 받은 n 값을 보존하기 위해 변수에 저장

    while (m--) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    for (int i = 1; i <= originalN; i++) { // originalN 값을 사용하여 반복문을 실행
        score[i] = bfs(i);
    }
    int min_kevin = *min_element(score + 1, score + 1 + originalN);
    for (int i = 1; i <= originalN; i++) { // originalN 값을 사용하여 반복문을 실행
        if (score[i] == min_kevin) {
            cout << i;
            return 0;
        }
    }
    return 0;
}

 

위와 같은 질문에 대한 답을 기다리면서 내가 어느 부분을 잘못썼을까, 메모리 접근이 잘못되게 만드는 부분이 무엇일까 생각해보면서 코드를 보다가

cin>>n>>m;

while(n--){

...

}

형태로 코드를 작성하여서, vertex의 값을 줄여버리고 있는 경우를 발견하게 되었다. 

이 문제의 경우 예제로 주어진 입력이 n=5, m=5 였기 때문에 그냥 예제입력을 입력을 입력해서

입력을 받는 갯수가 딱 주어진 간선의 길이와 같았기 때문에 코드가 돌아갔던 것이어서 n-- 형태로 코드를 작성했다는걸 파악하지 못했다. 

과거에도 이런식으로 vertex의 갯수와 간선의 갯수가 주어질때, 간선만큼의 반복문을 돌면서 입력을 받아야 하는데, 저 위치에 자꾸

vertex의 숫자인 n을 넣어서 입력을 제대로 받지 못한 경우들이 있었다. 

이렇게 n과 m이 딱 맞아버리는 예제를 주어버리면 그걸 찾아내기가 쉽지 않게 된다. 

애초부터 저 위치에 vertex의 갯수가 아니라 , edge의 갯수가 들어가야 한다는걸 확실하게 이해하고 그때에 제대로 된 코드를 작성하도록 하자. 

 

이번에 지피티에 제출해본 코드를 통해서 gpt가 내가 어떤 부분을 잘못했길래 이런식의 zsh: bus error 가 나오게 될지에 대해서 보완사항을 제시해 주었느데, 이번 질문에 대한 대답과, 제시해준 보완 사항이 꽤 괜찮은 방향성이라는 생각이 든다. 

지속적으로 알고리즘 문제를 풀면서 코드를 간결하게 작성하는 습관을 들이고 있으나, 지속적으로 실수하는 부분에 대해서는 간결보다는 잘못된 코드를 작성하지 않도록 안전장치를 마련하는 형태의 코드를 작성하도록 해야할 것 같다. 

값을 명시적으로 새로운 이름으로 선언해서 할당하고 그 값을 이용하는 형태의 개선점을 한번 앞으로 ps문제를 풀면서 코드를 작성할때 사용해보도록 하자. 

 

  Comments,     Trackbacks