Memleaking & freeing

Nejc Skoberne nejc.skoberne at guest.arnes.si
Sat May 10 10:10:02 CEST 2003


Zdravo.

Napisal sem en programcek v cju, ki izraz iz infiksne oblike pretvori
v post ter prefiksno obliko. Uporablja pac eno strukturo s katero si
pomagam zgraditi binarno drevo. Tri funkcije, ki jih potrebujem
delujejo rekurzivno - za parsanje, za sestavljanje rezultata ter za
brisanje celotne strukture.

Prvo moje vprasanje je, na kaj je potrebno biti pozoren pri freejanju
allociranega spomina v rekurzivnih funkcijah - namrec zgodilo se mi
je, da nekaterih zadev (aux0 in aux1) nisem mogel freejat (ce ne se je program cudno
obnasal) pa ceprav je izgledalo, da funkcija te zadeve ne potrebuje
vec. Na koncu sem pristal na tem, da sem razsiril strukturo tako, da
je vsak clen drevesa vseboval se dva pointerja - na tisto pomozno
zadevo, ki sem jo potem freejal kar ob freejanju celotnega drevesa.

Kodo prilagam.

Drugo vprasanje pa je, ali obstaja kje kaksen utility za preverjanje
memory leakinga v Cju? Nekaj sem Googlal pa nisem nasel nic
koristnega.

Hvala lepa.

-- 
Nejc Skoberne
Grajska ulica 5
SI-5220 Tolmin
E-mail: nejc.skoberne at guest.arnes.si
-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include "tree.h"

#define OPERATORS "+-*/"
#define MAX_RESULT_SIZE 8192

void Parse(PNode node, PNode parent, char *expr);
void CheckParentheses(char *expr);
void ToPrefix(PNode node);
void ToPostfix(PNode node);
void Concat(char *str, char *target);
char *PreResult;
char *PostResult;

int main(int argc, char *argv[])
{
	PreResult=(char *)malloc(MAX_RESULT_SIZE);
	PostResult=(char *)malloc(MAX_RESULT_SIZE);
	PNode root = CreateNode();
	int i=0;
	
	for (i=0;i<MAX_RESULT_SIZE;i++)
	{
		PreResult[i]=0;
		PostResult[i]=0;
	}
	
	CheckParentheses(argv[1]);
	Parse(root, NULL, argv[1]);
	ToPrefix(root);
	ToPostfix(root);
	DeleteNodes(root);
	printf("\nPrefix version: %s",PreResult);
	printf("\nPostfix version: %s\n\n",PostResult);
	free(PreResult);
	free(PostResult);
}

void Parse(PNode node, PNode parent, char *expr)
{
	int i=0, j=0, weight=0, go_on=1;
	char *expr_OK;
	char *aux0=NULL, *aux1=NULL, *aux2=NULL;
	PNode child1, child2;

	if (expr[0]=='(' && expr[strlen(expr)-1]==')')
	{		
		aux2 = (char *)malloc(strlen(expr)-2);
		strncpy(aux2, expr+1, strlen(expr)-2);
		for (i=0;i<strlen(aux2);i++)
		{	
			if (weight<0)
			{
				go_on=0;
				expr_OK = expr;
				break;
			}
			if (aux2[i]=='(') weight++;
			if (aux2[i]==')') weight--;
		}
		if (go_on)
		{
			expr_OK=aux2;
		}
	}
	else
	{
		expr_OK = expr;
	}	

	i=0;
	weight=0;	
	go_on=1;
	
	for (i=0;i<4;i++)
	{
		for (j=0;j<strlen(expr_OK);j++)
		{
			if (expr_OK[j]=='(') weight++;
			if (expr_OK[j]==')') weight--;
			if (expr_OK[j]==OPERATORS[i] && weight==0)
			{
				child1 = CreateNode();
				child2 = CreateNode();
				node->typ = 0;
				node->value = &OPERATORS[i];
				node->child_1 = child1;
				node->child_2 = child2;
				node->parent = parent;
				
				aux0=(char *)malloc(&expr_OK[j]-expr_OK);
				node->p1=aux0;
				Parse(child1, node, strncpy(aux0,expr_OK,&expr_OK[j]-expr_OK));
				aux1=(char *)malloc(expr_OK+strlen(expr_OK)-&expr_OK[j]);
				node->p2=aux1;
				Parse(child2, node, strncpy(aux1,&expr_OK[j]+1,(int)expr_OK+(int)strlen(expr_OK)-(int)&expr_OK[j]));
				go_on=0;
				weight=0;
				break;
			}	
		}		
		if (!(go_on)) break;
	}				
	if (go_on)
	{
		node->typ=1;
		node->value=expr_OK;
		node->parent=parent;
	}
	
	free(aux2);
}

void CheckParentheses(char *expr)
{
	printf("Checking syntax: %s ...",expr);
	int i=0;
	int weight=0;
	
	for (i=0;i<strlen(expr);i++)
	{
		if (expr[i]=='(') weight++;
		if (expr[i]==')') weight--;
	}
	
	if (weight != 0)
	{
		printf("Parentheses mismatch! Exiting ...\n");
		exit(1);
	}
	else 
	{
		printf("OK!\n");
	}
}
	
void ToPrefix(PNode node)
{
	char *tmp;
	if (node->typ==0)
	{
		tmp=(char *)malloc(sizeof(node->value));
		strcpy(tmp,node->value);
		tmp[1]=(int)NULL;
		Concat(tmp, PreResult);
		free(tmp);
		Concat("(", PreResult);
		ToPrefix(node->child_1);
		Concat(",", PreResult);
		ToPrefix(node->child_2);
		Concat(")", PreResult);
	}
	
	if (node->typ==1)
	{
		Concat(node->value, PreResult);
	}
}

void ToPostfix(PNode node)
{
	char *tmp;
	if (node->typ==0)
	{
		tmp=(char *)malloc(sizeof(node->value));
		strcpy(tmp,node->value);
		tmp[1]=(int)NULL;
		Concat("(", PostResult);
		ToPostfix(node->child_1);
		Concat(",", PostResult);
		ToPostfix(node->child_2);
		Concat(")", PostResult);
		Concat(tmp, PostResult);
		free(tmp);
	}
	
	if (node->typ==1)
	{
		Concat(node->value, PostResult);
	}
}

void Concat(char *str, char *target)
{
	strcat(target,str);
}














-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include "tree.h"

PNode CreateNode(void)
{
	PNode node = (PNode)malloc(sizeof(Node));
	node->typ = -1;
	node->value = NULL;
	node->p1 = NULL;
	node->p2 = NULL;
	node->parent = NULL;
	node->child_1 = NULL;
	node->child_2 = NULL;
	
	return node;
}

void DeleteNodes(PNode node)
{
	if (node->child_1 == NULL)
	{
		free(node);
	}
	else
	{
		DeleteNodes(node->child_1);
		DeleteNodes(node->child_2);
		free(node->p1);
		free(node->p2);
		free(node);
	}
}



-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

typedef void * PVoid;

struct SNode {
	int typ; // 0=value, 1=node
	PVoid value;
	char *p1;
	char *p2;
	struct SNode *parent;
	struct SNode *child_1;
	struct SNode *child_2;
	};
	
typedef struct SNode Node;
typedef Node * PNode;

PNode CreateNode(void);

void DeleteNodes(PNode node);



More information about the lugos-prog mailing list