C언어 포인터 관련하여, 실행했을 때 종종 결과값이 달라지는 경우는 어떻게 해결해야할까요?

조회수 2812회

똑같은 코드로 실행하였는데 3~5번에 1번 꼴로 잘못된 결과가 출력됩니다. 메모리 주소에 관련한 문제라고 어렴풋이 짐작은 가는데 해결하기위해 어떻게 접근해야 좋을 지 어려워 도움을 청하고자 합니다. 아래 사진은 제대로 출력된 결과입니다. 이미지

아래 사진이 같은 코드임에도 잘못된 실행결과입니다. 솔팅 후 첫번째 주소값을 읽어올 때 문제가 있는 것 같은데 그 이후는 또 제대로 읽을 수 있는것이 의아합니다.

이미지

어느 특정 부분에서 문제점이 있는지 판가름하기 어려워 코드 전체를 올리는 점 죄송합니다. 양해를 부탁드립니다.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct SCHEDULE
{
    char* time1;
    char* time2;
    int time1_h;
    int time1_m;
    int time2_h;
    int time2_m;
    char* appointment;
}Schedule;

void Split_line(FILE* ifp, int schedule_num, Schedule *schedule);
void Split_time(int schedule_num, Schedule *schedule);
void Sort_schedule(int schedule_num, Schedule *schedule);
void time_dif(int tmp_h, int tmp_m, int *max_h, int *max_m, int *start_h, int *start_m, int *start_nap_h, int *start_nap_m);
int Sweet_nap(int schedule_num, Schedule *schedule, int *start_nap_h, int *start_nap_m);

int main(void)
{
    FILE *ifp[3];
    int schedule_num=0;
    int start_nap_h = 10, start_nap_m = 0;
    int i;
    int nap_time, nap_h, nap_m;
    Schedule *schedule;

    ifp[0] = fopen("input1.txt", "r");
    ifp[1] = fopen("input2.txt", "r");
    ifp[2] = fopen("input3.txt", "r");

    for(i=0; i<3; i++){

        fscanf(ifp[i],"%d\n", &schedule_num);
        schedule = (Schedule*)malloc(sizeof(Schedule)*schedule_num);

        Split_line(ifp[i], schedule_num, schedule); // 각 라인을 time1, time2, appointment로 쪼개기
        Split_time(schedule_num, schedule); // 각 라인의 time1, time2 쪼개기
        Sort_schedule(schedule_num, schedule); // schedule 정렬하기     
        nap_time = Sweet_nap(schedule_num, schedule, &start_nap_h, &start_nap_m);

        nap_h = nap_time/60;
        nap_m = nap_time%60;
        if(nap_h == 0)
            printf("Day #%d: the longest nap starts at %d:%02d and will last for %02d minutes\n\n",i+1,start_nap_h, start_nap_m, nap_m);
        else
            printf("Day #%d: the longest nap starts at %d:%02d and will last for %d hours and %02d minutes\n\n",i+1,start_nap_h, start_nap_m, nap_h, nap_m);
    }
}

void Split_line(FILE* ifp, int schedule_num, Schedule *schedule){

    int i;
    char buff[99][255]; 
    printf("Schedule number : %d\n",schedule_num);
    for(i=0; i<schedule_num; i++){
        char* tmp;      
        fgets(buff[i], 255, (FILE*)ifp);
        tmp = strtok(buff[i]," ");
        schedule[i].time1 = tmp;
        tmp = strtok(NULL, " ");
        schedule[i].time2 = tmp;
        tmp = strtok(NULL, "\n");
        schedule[i].appointment = tmp;              
    }       
    fclose(ifp);        
}

void Split_time(int schedule_num, Schedule *schedule) {

    int i;
    char* tmp;  

    for(i=0; i<schedule_num; i++){

        tmp = strtok(schedule[i].time1,":");
        schedule[i].time1_h = atoi(tmp);
        tmp = strtok(NULL, ":");
        schedule[i].time1_m = atoi(tmp);

        tmp = strtok(schedule[i].time2,":");
        schedule[i].time2_h = atoi(tmp);
        tmp = strtok(NULL, ":");
        schedule[i].time2_m = atoi(tmp);        
        printf("Before sorting, %d:%02d %d:%02d %s\n",schedule[i].time1_h, schedule[i].time1_m,schedule[i].time2_h, schedule[i].time2_m ,schedule[i].appointment );
    }   
}

void Sort_schedule(int schedule_num, Schedule *schedule) {

    int i,j;
    Schedule tmp;

    for(i=0; i<schedule_num; i++) {
        for(j=0; j<schedule_num; j++) {
            if(schedule[j].time1_h > schedule[j+1].time1_h) {
                tmp = schedule[j];
                schedule[j] = schedule[j+1];
                schedule[j+1] = tmp;
            }
        }
    }
    for(i=0; i<schedule_num; i++)
        printf("After sorting, %d:%02d %d:%02d %s\n",schedule[i].time1_h, schedule[i].time1_m,schedule[i].time2_h, schedule[i].time2_m ,schedule[i].appointment );
}

void time_dif(int tmp_h, int tmp_m, int *max_h, int *max_m, int *start_h, int *start_m, int *start_nap_h, int *start_nap_m) {

    // 시간차에서 '시'가 현재 최대값보다 클 때
    if(tmp_h > *max_h) {
        *max_h = tmp_h;
        *max_m = tmp_m;
        *start_nap_h = *start_h;
        *start_nap_m = *start_m;
        /*printf("in 1st time_dif start_h : %d, start_m : %d\n",*start_nap_h, *start_nap_m);
        printf("in 1st time_dif tmp_h : %d, tmp_m : %d\n",tmp_h, tmp_m);
        printf("in 1st time_dif max_h : %d, max_m : %d\n", *max_h, *max_m);*/
        return;
    }
    // 시간차에서 '시'는 같고 '분'이 현재 최대값보다 클 때
    else if(tmp_h == *max_h && tmp_m > *max_m) {
        *max_h = tmp_h;
        *max_m = tmp_m;
        *start_nap_h = *start_h;
        *start_nap_m = *start_m;
        /*printf("in 2nd time_dif start_h : %d, start_m : %d\n",*start_nap_h, *start_nap_m);
        printf("in 2nd time_dif tmp_h : %d, tmp_m : %d\n",tmp_h, tmp_m);
        printf("in 2nd time_dif max_h : %d, max_m : %d\n", *max_h, *max_m);*/
        return;
    }
    else if(tmp_h == *max_h && tmp_m == *max_m) {
        /*printf("in 3rd time_dif start_h : %d, start_m : %d\n",*start_nap_h, *start_nap_m);
        printf("in 3rd time_dif tmp_h : %d, tmp_m : %d\n",tmp_h, tmp_m);
        printf("in 3rd time_dif max_h : %d, max_m : %d\n", *max_h, *max_m);*/
        return;
    }
}

int Sweet_nap(int schedule_num, Schedule *schedule, int *start_nap_h, int *start_nap_m) {

    int max_h = 0, max_m = 0;
    int start_H, start_M;
    int tmp_h, tmp_m;
    int i;

    for(i=0; i<schedule_num-1; i++) {

        //printf("%d:%d - %d:%d\n", schedule[i+1].time1_h,  schedule[i+1].time1_m,schedule[i].time2_h,schedule[i].time2_m);

        // 다음 스케쥴의 시작 h가 더 크고 m은 작을 때
        if(schedule[i].time2_h < schedule[i+1].time1_h && schedule[i].time2_m > schedule[i+1].time1_m) {
            tmp_m = 60 - schedule[i].time2_m;
            tmp_h = (schedule[i+1].time1_h - 1) - schedule[i].time2_h;
            time_dif(tmp_h, tmp_m, &max_h, &max_m, &(schedule[i].time2_h), &(schedule[i].time2_m), &start_H, &start_M);
            *start_nap_h = start_H;
            *start_nap_m = start_M;
            /*printf("%dth start_h : %d, start_m : %d\n",i,*start_nap_h, *start_nap_m);
            printf("%dth tmp_h : %d, tmp_m : %d\n",i,tmp_h, tmp_m);
            printf("%dth max_h : %d, max_m : %d\n",i,max_h, max_m);
*/
        }

        // 다음 스케쥴의 시작 h가 더 크거나 같고 m도 크거나 같을 때
        else if(schedule[i].time2_h <= schedule[i+1].time1_h && schedule[i].time2_m <= schedule[i+1].time1_m) {
            tmp_m = schedule[i+1].time1_m - schedule[i].time2_m;
            tmp_h = schedule[i+1].time1_h - schedule[i].time2_h;            
            time_dif(tmp_h, tmp_m, &max_h, &max_m, &(schedule[i].time2_h), &(schedule[i].time2_m), &start_H, &start_M);
            *start_nap_h = start_H;
            *start_nap_m = start_M;
            /*printf("%dth start_h : %d, start_m : %d\n",i,*start_nap_h, *start_nap_m);
            printf("%dth tmp_h : %d, tmp_m : %d\n",i,tmp_h, tmp_m);
            printf("%dth max_h : %d, max_m : %d\n",i,max_h, max_m);     */     
        }
    }
    //printf("Final max_h : %d, max_m : %d\n", max_h, max_m);
    return (60 * max_h) + max_m;
}
  • (•́ ✖ •̀)
    알 수 없는 사용자
  • 파일내용도 올려주시겠어요 알 수 없는 사용자 2016.9.5 10:22
  • 같이 고민해주신 것에 정말 정말 감사합니다. 덕분에 다행히도 해결할 수 있었습니다. sorting하는 함수에서 bubble sorting을 구글링하여 그대로 가져왔는데 거기서 문제가 있었습니다. 혹시라도 해결책을 찾고 계신 와중 궁금하셨을까하여 고치 사항을 아래 답변으로 올리겠습니다. bubble sorting일 때 됬다 안됬다 하는 이유는 아직도 명확히 잘 모르겠네요ㅠㅠ 포인터는 참 어렵습니다ㅠㅠ 알 수 없는 사용자 2016.9.5 10:45
  • 되다 안되다 하는게 정렬결과가 일정하지 않다는 말씀인가요? 아니면 위의 결과처럼 이상한 값을 출력한다는건가요? 그리고 파일이 세개다 그런 결과가 나타나나요? 알 수 없는 사용자 2016.9.5 11:32
  • 위의 코드의 문제점을 나열하겠습니다. 1) 실행결과가 랜덤하게 다르다.(위의 사진 2가지처럼 잘나왔다가 이상한값이 나왔다가 한다는 뜻) 2) input파일 3개의 순서를 바꾸어도 실행결과가 랜덤하게 나온다.(1번과 동일) 3) input 파일 3개의 순서를 바꾸어도 위의 사진과 같은 부분에서'만' 이상한 값이 출력된다. 추가로 아래에 input.txt 파일 3개를 모두 올리겠습니다. 알 수 없는 사용자 2016.9.5 11:40
  • 제가 요즘 많이 바빠서 이걸 볼 여력이 안되네요 주말에라도 여력이 생기면 좀 한번 봐불게요 궁금은해서요. 혹시 해결 됐음 내려주세요 ㅋ 알 수 없는 사용자 2016.9.6 23:25

1 답변

  • input1.txt 파일내용 입니다.

    4
    11:00 12:00 Lectures
    12:00 13:00 Lunch, like always
    13:30 15:00 Boring lectures
    16:45 17:45 Reading
    

    input2.txt 파일내용 입니다.

    5
    10:00 10:30 Algorithm
    11:00 12:00 Graphics
    15:30 16:30 Web programming
    17:00 18:00 Network
    12:00 15:00 Marketing
    

    input3.txt 파일내용 입니다.

    3
    14:00 15:00 Seminar
    11:00 13:00 Lectures
    16:30 17:00 Study
    
    

    sorting을 insertion sorting으로 바꾸었습니다.

    void Sort_schedule(int schedule_num, Schedule *schedule) {
    
        int i,j;
        Schedule tmp;
    
        for (i = 1 ; i <= schedule_num - 1; i++) {
            j = i;
    
            while (j > 0 && schedule[j].time1_h < schedule[j-1].time1_h) {
                tmp = schedule[j];
                schedule[j] = schedule[j-1];
                schedule[j-1] = tmp;
                j--;
            }
        }
        for(i=0; i<schedule_num; i++)
            printf("After sorting, %d:%02d %d:%02d %s\n",schedule[i].time1_h, schedule[i].time1_m,schedule[i].time2_h, schedule[i].time2_m ,schedule[i].appointment );
    }
    
    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)