편집 기록

편집 기록
  • 프로필 알 수 없는 사용자님의 편집
    날짜2017.11.06

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


    똑같은 코드로 실행하였는데 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;
    }