[완료]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 2Forums:


free에서 런타임 에러가 발생한다는 건 보통 힙이
free에서 런타임 에러가 발생한다는 건 보통 힙이 깨졌다는 걸 의미합니다.
주어진 코드와 같이 힙에 가변 길이 자료구조를 올려놓고 접근하는 경우, 주의하지 않으면 할당된 범위 밖을 접근하면서 힙을 깨트릴 가능성이 매우 높습니다.
문제는, 힙이 깨진 즉시 에러가 나는 게 아니라 잘 도는 것처럼 보이다가 나중에 터진다는 거죠. 설령 눈에 띄는 에러가 발생하지 않는다고 해도 프로그램이 정상적으로 동작한다는 보장도 없고요. 복불복이죠.
문제가 여럿 있을 수 있지만 일단 가장 눈에 띄는 것 하나 먼저 지적하지요.
main함수는 시작하자마자 아래와 같은 코드로 동적 배열을 할당하는데,
그 시점에서는 아직 사용자 입력을 읽지 않았기 때문에(inputdata) 전역 변수 edgeNum의 값은 0입니다. 터무니없이 작은 배열을 할당한 것이지요.
이후 사용자 입력을 받아 edgeNum에 0보다 큰 값이 들어가면 dfs나 dfs_visit 등의 함수들은 할당받은 배열 밖에 값을 읽고 쓰고 합니다. 그 결과 힙이 개판이 되고 나중에 free할 때 프로그램이 깨지는 겁니다.
아! 답변 감사합니다. 그러네요. input을
아! 답변 감사합니다. 그러네요. input을 받기전에 먼저 malloc을 먼저 하는군요 정말 답변 감사합니다.
그부분을 해결하면 깔끔하게 돌아가네요.!!
댓글 달기