What I'm working on right now is a state-based parser for any input from a stream. My professor tells me this is the best way to avoid special cases. The way I've got it set up is using functions, and I'm having a little bit of trouble trying to reuse allocated memory so I don't cause any leaks. What I am parsing are multiple parameters. Each parameter has a name and a value. An example input would be:
parameterName = 500;
The name is parameterName and it is of type integer with a value of 500.
I am successfully able to parse one of these without memory leaks. However, doing a second parameter will cause leaks and I know why: It's the multiple uses of malloc on my parameter name.
Take a look at the parsing code:
int main()
{
int x;
char c;
char *nameTemp;
int hasName = 0;
int hasEqual = 0;
/* ParameterManager values */
ParameterManager *pm;
pm = PM_create(500);
if((PM_manage(pm, "name", INT_TYPE, 1)));
while((x = getchar()) != EOF)
{
/* Cast int to char */
c = (char)x;
/* Whitespace state */
if((isspace(c)))
{
c = whitespace();
}
/* Comment state */
if(c == '#')
{
c = comment();
}
/* Name state */
if(((isalnum(c)) && hasEqual == 0 && hasName == 0))
{
nameTemp = name(c);
printf("Name: %s\n", nameTemp);
hasName = 1;
}
/* Equal state */
if(c == '=' && hasName == 1 && hasEqual == 0)
{
hasEqual = 1;
}
/* Value state */
if((isalnum(c)) && hasName == 1 && hasEqual == 1)
{
getValues(c, nameTemp, pm->t_List, pm->m_List);
hasName = 0;
hasEqual = 0;
}
}
free(nameTemp);
if((PM_destroy(pm)) && DEBUG) printf("Success destroying PM.\n");
return 0;
}
The line nameTemp = name(c)
, under /* Name state */
, returns an allocated string. This string is later passed to do other work. However, since this whole parsing idea is in a loop, multiple mallocs to the same string will be made. I can only free nameTemp once but there are multiple mallocs on that name. How can I reuse nameTemp over and over without causing any leaks?
Here is a piece of code (in function name()
) where nameTemp is allocated:
/* Make sure temp is not NULL before mallocing */
if(temp[0] != '\0')
{
returnName = malloc(sizeof(char)*strlen(temp)+1);
strncpy(returnName, temp, strlen(temp)+1);
temp[0] = '\0';
return returnName;
}
I apologize if a few things are unclear. I'm trying to be as general as I can so if you need more clarification please let me know.