malloc & free 질문입니다.

lovejin0309의 이미지

다음과 같은 구조체가 있습니다.

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
}

lovejin0309의 이미지

전체 소스를 올리면 계속 깨져서 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;
}

pynoos의 이미지

for(i=0; i countOfChild ; i++){

XmlTreeDestructor에서 Leaf NODE가 아닌곳의 for 문 비교에 countOfChild 가 아니라 source->countOfChild 같은데요?

pynoos의 이미지

음.. drupal 이 잡아 먹었나보군요. 없으면 컴파일이 안될텐데...

dionysos의 이미지

한방에 할수 있는 방법을 찾으신다면 메모리를 대량으로 할당하고 메모리 리스트를 관리하는 메모리 풀을 사용하시면 됩니다.

노력은 배반하지 않는다.

노력은 배반하지 않는다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.