[완료]C code - free만 쓰면. 코드가 터집니다.. 어떤점이 문제인가요?
글쓴이: KD K@Google / 작성시간: 월, 2017/11/13 - 7:26오후
안녕하세요
알고리즘 공부중입니다.
입력받은 파일을 linkList로 만든후
DFS로 Topological Sort 를 생성.
longest path를 찾는 문제입니다.
알고리즘 상 문제는 없어보이는데..
문제는 main 함수 마지막에 free를 쓰면 값은 모두출력되는데
출력후 프로그램이 정지합니다.
free를 안쓰면 잘돌아가구요.
free쓰는것에 뭐가 문제가 있나요?
그리고.
아무리 봐도 제 코드가 지저분해 보이는데
코드를 깔끔하게 짜는데 참고할만한 것있으면[책이라던가.. 사이트라던가].. 조언부탁드립니다.
#include<stdio.h> #include<stdlib.h> #define WHITE 0 #define GRAY -1 #define BLACK 1 typedef struct element *eleptr; typedef struct element { int extend; int height; int weight; }element; typedef struct node *nodeptr; typedef struct node { int to; int w; nodeptr link; }node; int edgeNum; nodeptr tp_header = NULL; element *inArr =NULL; nodeptr *listhead =NULL; /////////////dfs////////// int * p = NULL; int * d = NULL; int * color = NULL; int p2[50]; int d2[50]; void dfs_visit(int u); void dfs(); ////////////////// nodeptr mknode(int to, int w); void inputdata(); void mkList(); void printfList(); void DSP(); void relax(int u,int v); int main(void) { int i; p=(int*)malloc(sizeof(int)*(edgeNum+2)); color=(int*)malloc(sizeof(int)*(edgeNum+2)); d=(int*)malloc(sizeof(int)*(edgeNum+2)); inputdata(); mkList(); printfList(); dfs(); DSP(); for(i=0;i<edgeNum+2;i++) { printf(" %d",d2[i]); } printf("\n"); for(i=0;i<edgeNum+2;i++) { printf(" %d",p2[i]); } printf("\n"); for(i=edgeNum+1;i!=0;i=p2[i]) { printf(" %d",p2[i]); } printf("\n"); printf(" %d\n",d2[edgeNum+1]); free(p); free(color); free(d); free(listhead); free(inArr); return 0; } nodeptr mknode(int to, int w) { nodeptr tmp; tmp = (nodeptr)malloc(sizeof(node)); tmp->to=to; tmp->w=w; tmp->link=NULL; return tmp; } void inputdata() { FILE *fp_input; char file_name[30]; int i,j; printf("input ifle name?"); scanf("%s",file_name); fp_input = fopen(file_name,"r"); if(fp_input == NULL) { fprintf(stderr,"FILE <%s> open error.\n",file_name); exit(1); } fscanf(fp_input,"%d",&edgeNum); inArr = (eleptr)malloc(sizeof(element)*(edgeNum+3)); inArr[0].extend=9999; inArr[0].height=0; inArr[0].weight=9999; for(i=1;i<=edgeNum;i++) { fscanf(fp_input,"%d %d %d",&(inArr[i].extend),&(inArr[i].height),&(inArr[i].weight)); } inArr[edgeNum+1].extend=0; inArr[edgeNum+1].height=0; inArr[edgeNum+1].weight=0; } void mkList() { int i,j ; nodeptr tmp; listhead = (nodeptr*)malloc(sizeof(nodeptr)*(edgeNum+2)); for(i=0;i<edgeNum+2;i++) listhead[i]=NULL; for(i=0;i<=edgeNum+1;i++) { for(j=i;j<=edgeNum+1;j++) { if(inArr[i].extend <inArr[j].extend && inArr[i].weight < inArr[j].weight) {// i 의 돌이 j 의 돌보다 작고 가벼우면 j->i 로 연결 tmp=mknode(i,inArr[j].height); if(listhead[j]==NULL) { listhead[j]=tmp; } else { tmp->link=listhead[j]; listhead[j]=tmp; } } else if(inArr[i].extend >inArr[j].extend && inArr[i].weight > inArr[j].weight) { tmp=mknode(j,inArr[i].height); if(listhead[i]==NULL) { listhead[i]=tmp; } else { tmp->link=listhead[i]; listhead[i]=tmp; } } } } } void printfList() { int i; nodeptr temp=NULL; for(i=0;i<edgeNum+2;i++) { temp=listhead[i]; printf("from%2d =>",i); while(temp!=NULL) { printf("[to=%2d h=%2d] -->",temp->to,temp->w); temp=temp->link; } printf(" X"); printf("\n"); } } void DSP() { int i; nodeptr temp; nodeptr temp2; for(i=0;i<edgeNum+2;i++) { d2[i]=0; p2[i]=NULL; } d2[0]=0; temp=tp_header; while(temp!=NULL) { temp2=listhead[temp->to]; while(temp2!=NULL) { relax(temp->to,temp2->to); temp2=temp2->link; } temp=temp->link; } } void relax(int u,int v) { if(d2[v] < d2[u] + inArr[u].height) { d2[v] = d2[u] +inArr[u].height; p2[v] = u; } } void dfs() { int i,j; nodeptr temp; for(i=0;i<edgeNum+2;i++) { p[i]=-1; color[i]=WHITE; } for(i=0;i<edgeNum+2;i++) { if(color[i]==WHITE) { dfs_visit(i); } } printf("TP\n"); temp=tp_header; while(temp!=NULL) { printf("%3d",temp->to); temp=temp->link; } printf("\n"); } void dfs_visit(int u) { nodeptr temp; nodeptr cur = listhead[u]; color[u] =GRAY; while(cur) { if(color[cur->to]==WHITE) { p[cur->to] = u; dfs_visit(cur->to); } cur = cur->link; } color[u]=BLACK; temp=mknode(u,0); temp->link=tp_header; tp_header=temp; } <code> input 5 25 3 4 4 4 6 9 2 3 16 2 5 1 5 2
Forums:
free에서 런타임 에러가 발생한다는 건 보통 힙이
free에서 런타임 에러가 발생한다는 건 보통 힙이 깨졌다는 걸 의미합니다.
주어진 코드와 같이 힙에 가변 길이 자료구조를 올려놓고 접근하는 경우, 주의하지 않으면 할당된 범위 밖을 접근하면서 힙을 깨트릴 가능성이 매우 높습니다.
문제는, 힙이 깨진 즉시 에러가 나는 게 아니라 잘 도는 것처럼 보이다가 나중에 터진다는 거죠. 설령 눈에 띄는 에러가 발생하지 않는다고 해도 프로그램이 정상적으로 동작한다는 보장도 없고요. 복불복이죠.
문제가 여럿 있을 수 있지만 일단 가장 눈에 띄는 것 하나 먼저 지적하지요.
main함수는 시작하자마자 아래와 같은 코드로 동적 배열을 할당하는데,
그 시점에서는 아직 사용자 입력을 읽지 않았기 때문에(inputdata) 전역 변수 edgeNum의 값은 0입니다. 터무니없이 작은 배열을 할당한 것이지요.
이후 사용자 입력을 받아 edgeNum에 0보다 큰 값이 들어가면 dfs나 dfs_visit 등의 함수들은 할당받은 배열 밖에 값을 읽고 쓰고 합니다. 그 결과 힙이 개판이 되고 나중에 free할 때 프로그램이 깨지는 겁니다.
아! 답변 감사합니다. 그러네요. input을
아! 답변 감사합니다. 그러네요. input을 받기전에 먼저 malloc을 먼저 하는군요 정말 답변 감사합니다.
그부분을 해결하면 깔끔하게 돌아가네요.!!
댓글 달기