malloc & free 질문입니다.
글쓴이: lovejin0309 / 작성시간: 목, 2006/06/15 - 4:36오후
다음과 같은 구조체가 있습니다.
struct xmlTagNode{
struct xmlTagNode *parentNode;
struct xmlTagNode *childNodes[50];
char *nodeName;
char *nodeValue;
int countOfChild;
};위 구조체를 사용해서 다음과 같이 메모리를 할당했습니다.
struct xmlTagNode *temp; temp = (struct xmlTagNode *)malloc(sizeof(xmlTagNode)); temp->nodeName = (char *)malloc(24); temp->nodeValue = (char *)malloc(64);
구조체 맴버 중에서 parentNode, childNodes 는 다른 노드와 연결하는 부분입니다.
이런식으로 트리를 작성한 후, 그 트리를 없애는 함수를 작성했습니다.
질문입니다.
위처럼 구조체를 malloc으로 잡은 후 그 구조체를 없앨 때는 맴버들을 일일히 없애 주어야 하나요?
free(temp->parents); free(temp->childNodes); free(temp->nodeName); free(temp->nodeValue); free(temp->countOfChild); free(temp);
이런식으로 해야 하나요?
====================
xml 메시지를 받아서 트리 형태로 작성하는 프로그램을 짜고 있습니다. 한번만 돌리면 문제가 없는데
만들고, 지우고, 만들고, 지우고 하면 패닉이 발생합니다. 도움 부탁 드립니다.
다음은 원본 소스입니다.
#include <stdio.h>
#include <stdlib.h>
#define LIMIT_CHILD_NODE 20
struct xmlTagNode{
struct xmlTagNode *parentNode;
struct xmlTagNode *childNodes[50];
char *nodeName;
char *nodeValue;
int countOfChild;
};
struct StackXmlTag{
int sp;
struct xmlTagNode *stack[10];
}stackOfXmlTag;
struct xmlTagNode RootOfxmlDomTree;
int main(int argc, char *argv[])
{
char BUF[1024];
char ch;
int ret;
// ret = Read_XML_dat(BUF, argv[1]);
ret = Remove_NULL_char(BUF);
/* Root 노드 초기화 */
RootOfxmlDomTree.nodeName = (char *)malloc(sizeof(char) * 16);
strcpy(RootOfxmlDomTree.nodeName, "Root_node");
strcpy(BUF,"<message><header><type>event</type><dest></dest><command></command><feedback></feedback></header><body><event><eid>040101</eid><name>화재발생</name><desc>화재가발생했습니다.</desc><service><name>open</name><argument>on</argument></service> </event> </body></message>");
ret = Remove_NULL_char(BUF);
RootOfxmlDomTree.countOfChild = 0;
/* STACK 초기화 */
memset(stackOfXmlTag.stack, '\0', sizeof(stackOfXmlTag.stack));
stackOfXmlTag.sp = 0;
ret = XmlTreeCreator(BUF);
// stackOfXmlTag.sp = 0;
while(1){
ret = XmlTreeDestructor(&RootOfxmlDomTree, "hi");
}
return 0;
}
int Read_XML_dat(char *BUF, char *FILE_NAME)
{
FILE *FD;
int i;
FD = fopen(FILE_NAME, "r");
i = 0;
memset(BUF, '\0', sizeof(BUF));
while(1)
{
BUF[i]=fgetc(FD);
if(BUF[i] == EOF) break;
if(i>1020) printf("오버플로우 조심\n\n\n");
i++;
}
fclose(FD);
return strlen(BUF);
}
int XmlTreeCreator(char *BUF)
{ char TAG[128];
int count;
int ret;
int sizeNode;
int countOfChild;
struct xmlTagNode *temp;
count = strlen(BUF);
sizeNode = sizeof(struct xmlTagNode);
/* STACK 에 루트 노드 push */
stackOfXmlTag.sp = 0;
stackOfXmlTag.stack[stackOfXmlTag.sp] = &RootOfxmlDomTree;
while(1)
{
ret = Extract_XML_Tag(TAG, BUF);
/* 자식 노드 생성 및 스택 push */
if(TAG[0] == '<' && TAG[1] != '/' && TAG[strlen(TAG)-1] == '>') {
/* 노드 생성 및 초기화 */
temp = (struct xmlTagNode *)malloc(sizeNode);
temp->nodeName = (char *)malloc(strlen(TAG));
strcpy(temp->nodeName, TAG);
temp->countOfChild = 0;
/* 스택 push */
stackOfXmlTag.sp++;
stackOfXmlTag.stack[stackOfXmlTag.sp] = temp;
/* 부모 노드와 연결 */
countOfChild = stackOfXmlTag.stack[stackOfXmlTag.sp - 1]->countOfChild;
stackOfXmlTag.stack[stackOfXmlTag.sp - 1]->childNodes[countOfChild] = stackOfXmlTag.stack[stackOfXmlTag.sp]; // 부모노드-> 자식노드
stackOfXmlTag.stack[stackOfXmlTag.sp]->parentNode = stackOfXmlTag.stack[stackOfXmlTag.sp - 1]; // 자식노드 -> 부모노드
stackOfXmlTag.stack[stackOfXmlTag.sp - 1]->countOfChild++;// 자식 노드의 숫자를 늘려준다.
}
/* 현재 노드에 Value 를 넣음 */
if(strlen(TAG) > 0 && TAG[0] != '<' && TAG[1] != '/' && TAG[strlen(TAG)-1] != '>') {
stackOfXmlTag.stack[stackOfXmlTag.sp]->nodeValue = (char *)malloc(strlen(TAG));
strcpy(stackOfXmlTag.stack[stackOfXmlTag.sp]->nodeValue, TAG);
}
/* STACK POP */
if(TAG[0] == '<' && TAG[1] == '/' && TAG[strlen(TAG)-1] == '>') {
stackOfXmlTag.sp--;
}
/* DOM work-tree 생성 과정을 종료하기 위한 작업 */
count = count - strlen(TAG);
if(ret == EOF || count <= 0) return 0;
}// end of while
}Forums:


전체 소스를 올리면
전체 소스를 올리면 계속 깨져서 free 시키는 함수는 댓글로 올립니다.
int XmlTreeDestructor(struct xmlTagNode *source, char *keyText) { int i; int ret; if(source->countOfChild <= 0){// Leaf NODE 라면 // 할당된 메모리 해제 printf("%s\n",source->nodeName); free(source->nodeName); free(source->nodeValue); return 0; }else{ // Leaf NODE가 아니라면 printf("부모 노드 %s\n",source->nodeName); for(i=0; i < source->countOfChild ; i++){ ret = XmlTreeDestructor(source->childNodes[i],"hi"); free(source->childNodes[i]); } source->countOfChild = 0; } return 0; }for(i=0; i countOfChild ;
for(i=0; i countOfChild ; i++){
XmlTreeDestructor에서 Leaf NODE가 아닌곳의 for 문 비교에 countOfChild 가 아니라 source->countOfChild 같은데요?
---
http://coolengineer.com
음.. drupal 이 잡아
음.. drupal 이 잡아 먹었나보군요. 없으면 컴파일이 안될텐데...
---
http://coolengineer.com
malloc한만큼 free를 해주어야 하는걸로 알고 있습니다.
한방에 할수 있는 방법을 찾으신다면 메모리를 대량으로 할당하고 메모리 리스트를 관리하는 메모리 풀을 사용하시면 됩니다.
노력은 배반하지 않는다.
노력은 배반하지 않는다.
댓글 달기