fix: mem leak, test: config parsing until 300000lines and over 1 million structs
This commit is contained in:
85
config.c
85
config.c
@@ -2,6 +2,7 @@
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<string.h>
|
||||
#include<errno.h>
|
||||
/*
|
||||
* Here we check if the given string contains a section
|
||||
* for example [SECTIONName] here delimiterLeft is [ and delimiterRight is ]
|
||||
@@ -27,14 +28,12 @@ int checkSection(char *str,char delimiterLeft,char delimiterRight,char **section
|
||||
return ERROR_STR;
|
||||
}
|
||||
int len = strlen(str);
|
||||
printf("strlen: %d",len);
|
||||
int state = ST_INIT;
|
||||
int leftDelimiterPos=0;
|
||||
int rightDelimiterPos=0;
|
||||
char *sectionName2 = NULL;
|
||||
while(state != ST_FINISH)
|
||||
{
|
||||
printf("STATE:%i\n",state);
|
||||
switch(state)
|
||||
{
|
||||
case ST_INIT:
|
||||
@@ -96,6 +95,12 @@ int checkSection(char *str,char delimiterLeft,char delimiterRight,char **section
|
||||
|
||||
int getStrAtPos(char *str,int fromPos,int toPos,char **name,int sizeName)
|
||||
{
|
||||
if(*name == NULL)
|
||||
{
|
||||
int error = errno;
|
||||
printf("Pointer NULL:%d\n",error);
|
||||
return error;
|
||||
}
|
||||
int i=fromPos; //character iterator, which starts from specified pos
|
||||
int j=0; //the character iterator for the target string
|
||||
int diffLen=toPos-fromPos;
|
||||
@@ -109,7 +114,6 @@ int getStrAtPos(char *str,int fromPos,int toPos,char **name,int sizeName)
|
||||
ptr_name[j] = str[i];
|
||||
}
|
||||
ptr_name[j+1]='\0';
|
||||
//printf("*name:%s\n",ptr_name);
|
||||
return NO_ERROR;
|
||||
}
|
||||
/*
|
||||
@@ -144,6 +148,12 @@ int getStrAtPos(char *str,int fromPos,int toPos,char **name,int sizeName)
|
||||
|
||||
int getNameValuePair(char *str,char leftDelimiterPos,char rightDelimiterPos,char **name,char **value,int sizeName,int sizeValue)
|
||||
{
|
||||
if(*name == NULL || *value == NULL)
|
||||
{
|
||||
int error = errno;
|
||||
printf("Pointer NULL:%d\n",error);
|
||||
return error;
|
||||
}
|
||||
int state=ST_INIT;
|
||||
char *ptr_name=*name;
|
||||
char *ptr_value=*value;
|
||||
@@ -159,11 +169,12 @@ int getNameValuePair(char *str,char leftDelimiterPos,char rightDelimiterPos,char
|
||||
return ERROR_DELIMITER_NOT_FOUND;
|
||||
}
|
||||
posDelimiter = (ptrDelimiter - str);
|
||||
printf("LenUntilDelimiter: %d",posDelimiter);
|
||||
printf("LenUntilDelimiter: %d\n",posDelimiter);
|
||||
if((ret=getStrAtPos(str,0,posDelimiter-1,&ptr_name,sizeName)) == NO_ERROR)
|
||||
{
|
||||
printf("ptr_name:%s",ptr_name);
|
||||
printf("ptr_name:%s\n",ptr_name);
|
||||
}else {
|
||||
printf("Error at getStrAtPos:%d\n",ret);
|
||||
return ret;
|
||||
}
|
||||
if(rightDelimiterPos == 0)
|
||||
@@ -185,15 +196,33 @@ int getNameValuePair(char *str,char leftDelimiterPos,char rightDelimiterPos,char
|
||||
|
||||
|
||||
|
||||
int parseConfig(char *buffer,struct configEntry **entry,int configSizeCount,int *returnedCount)
|
||||
int parseConfig(char *originalBuffer,struct configEntry **entry,int configSizeCount,int *returnedCount)
|
||||
{
|
||||
int state=ST_INIT;
|
||||
int ret=0;
|
||||
int i=0;
|
||||
*returnedCount=0;
|
||||
char *sectionName=NULL;
|
||||
struct configEntry *ptr_entry = *entry;
|
||||
char *keyName=NULL;
|
||||
char *keyValue=NULL;
|
||||
char *buffer=NULL;
|
||||
|
||||
buffer = malloc(strlen(originalBuffer)+1);
|
||||
if(buffer == NULL)
|
||||
{
|
||||
int error = errno;
|
||||
printf("ERROR MALLOC:%d",error);
|
||||
return ERR_PARSECONFIG_UNKNOWN;
|
||||
}
|
||||
memset(buffer,0,strlen(originalBuffer)+1);
|
||||
strcpy(buffer,originalBuffer);
|
||||
|
||||
//this step is necessary, because the strok function modifys the originalBuffer
|
||||
//so we make a copy of it
|
||||
strcpy(buffer,originalBuffer);
|
||||
|
||||
printf("buffer:%s\n--",buffer);
|
||||
|
||||
sectionName = malloc(MAX_LEN_SECTIONNAME);
|
||||
memset(sectionName,0,MAX_LEN_SECTIONNAME);
|
||||
@@ -203,47 +232,47 @@ int parseConfig(char *buffer,struct configEntry **entry,int configSizeCount,int
|
||||
token = strtok(buffer,"\n");
|
||||
while(token != NULL && state != ST_FINISH)
|
||||
{
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case ST_INIT:
|
||||
printf("token(line): %s\n",token);
|
||||
|
||||
if((ret=checkSection(token,'[',']',§ionName))==FOUND_SECTION)
|
||||
{
|
||||
state = ST_FOUND_SECTION;
|
||||
printf("FOUND_SECTION:%s\n",sectionName);
|
||||
}
|
||||
break;
|
||||
case ST_FOUND_SECTION:
|
||||
keyName = malloc(MAX_LEN_SECTIONNAME);
|
||||
keyValue = malloc(MAX_LEN_SECTIONNAME);
|
||||
if(keyName == NULL || keyValue == NULL)
|
||||
{
|
||||
int error = errno;
|
||||
printf("MALLOC:%d\n",error);
|
||||
//return error;
|
||||
}
|
||||
memset(keyName,0,MAX_LEN_SECTIONNAME);
|
||||
memset(keyValue,0,MAX_LEN_SECTIONNAME);
|
||||
if((ret=getNameValuePair(token,'=',0,
|
||||
&keyName,&keyValue,
|
||||
MAX_LEN_SECTIONNAME,MAX_LEN_SECTIONNAME
|
||||
))==NO_ERROR)
|
||||
|
||||
ret=getNameValuePair(token,'=',0,&keyName,&keyValue,MAX_LEN_SECTIONNAME,MAX_LEN_SECTIONNAME);
|
||||
if(ret==NO_ERROR)
|
||||
{
|
||||
ptr_entry[i].sectionName = strdup(sectionName);
|
||||
ptr_entry[i].keyValue= strdup(keyValue);
|
||||
ptr_entry[i].keyName = strdup(keyName);
|
||||
free(keyName);
|
||||
free(keyValue);
|
||||
if(i<configSizeCount-1)
|
||||
printf("configSizeCount: %d, i:%d\n",configSizeCount,i);
|
||||
if(i<configSizeCount)
|
||||
{
|
||||
i++;
|
||||
*returnedCount = i;
|
||||
}
|
||||
else {
|
||||
free(sectionName);
|
||||
return ERROR_STR;
|
||||
ptr_entry[i].sectionName = strdup(sectionName);
|
||||
ptr_entry[i].keyValue= strdup(keyValue);
|
||||
ptr_entry[i].keyName = strdup(keyName);
|
||||
}
|
||||
i++;
|
||||
*returnedCount = i;
|
||||
state = ST_FOUND_SECTION;
|
||||
}
|
||||
else {
|
||||
free(keyName);
|
||||
free(keyValue);
|
||||
state = ST_SKIP_READ;
|
||||
}
|
||||
free(keyName);
|
||||
free(keyValue);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -255,7 +284,11 @@ int parseConfig(char *buffer,struct configEntry **entry,int configSizeCount,int
|
||||
state = ST_INIT;
|
||||
}
|
||||
}
|
||||
printf("token: %s\n",token);
|
||||
printf("buffer:%s\n--",buffer);
|
||||
|
||||
free(sectionName);
|
||||
free(buffer);
|
||||
printf("finish exitting parsing\nSTATE:%d\n",state);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
99
config.cfg
99
config.cfg
@@ -1,66 +1,43 @@
|
||||
[PRINTER]
|
||||
ip=192.168.209.173
|
||||
a=193
|
||||
b=111
|
||||
1234567891
|
||||
ip=192.168.209.173
|
||||
[PRINTER]
|
||||
[PRINTER]
|
||||
[PRINTER]
|
||||
[PRINTER]
|
||||
[PRINTER]
|
||||
[PRINTER]
|
||||
[PRINTER]
|
||||
[PRINTER]
|
||||
[PRINTER]
|
||||
[PRINTER]
|
||||
ip=192.168.209.173
|
||||
a=193
|
||||
b=111
|
||||
1234567891
|
||||
ip=192.168.209.173
|
||||
ip=192.168.209.173
|
||||
a=193
|
||||
b=111
|
||||
1234567891
|
||||
ip=192.168.209.173
|
||||
ip=192.168.209.173
|
||||
a=193
|
||||
b=111
|
||||
1234567891
|
||||
ip=192.168.209.173
|
||||
ip=192.168.209.173
|
||||
a=193
|
||||
b=111
|
||||
1234567891
|
||||
ip=192.168.209.173
|
||||
ip=192.168.209.173
|
||||
a=193
|
||||
b=111
|
||||
1234567891
|
||||
ip=192.168.209.173
|
||||
ip=192.168.209.173
|
||||
a=193
|
||||
b=111
|
||||
1234567891
|
||||
ip=192.168.209.173
|
||||
ip=192.168.209.173
|
||||
a=193
|
||||
b=111
|
||||
1234567891
|
||||
ip=192.168.209.173
|
||||
ip=192.168.209.173
|
||||
a=193
|
||||
b=111
|
||||
1234567891
|
||||
ip=192.168.209.173
|
||||
ip=192.168.209.173
|
||||
a=193
|
||||
b=111
|
||||
1234567891
|
||||
ip=192.168.209.173
|
||||
b=111
|
||||
1234567891
|
||||
ip=192.168.209.173
|
||||
[PRINTER1]
|
||||
a=1
|
||||
[PRINTER2]
|
||||
b=2
|
||||
[PRINTER3]
|
||||
c=3
|
||||
[PRINTER4]
|
||||
d=4
|
||||
[PRINTER5]
|
||||
e=5
|
||||
[PRINTER6]
|
||||
f=6
|
||||
[PRINTER7]
|
||||
g=7
|
||||
[PRINTER8]
|
||||
h=8
|
||||
[PRINTER9]
|
||||
ip=192.168.209.173
|
||||
a=193
|
||||
b=111
|
||||
1234567891
|
||||
ip=192.168.209.173
|
||||
[PRINTER10]
|
||||
i=9
|
||||
[PRINTER11]
|
||||
j=10
|
||||
[PRINTER12]
|
||||
k=11
|
||||
[PRINTER13]
|
||||
l=12
|
||||
[PRINTER14]
|
||||
m=13
|
||||
[PRINTER15]
|
||||
n=14
|
||||
[PRINTER16]
|
||||
o=15
|
||||
[PRINTER17]
|
||||
p=16
|
||||
[PRINTER18]
|
||||
q=§20
|
||||
|
||||
5
config.h
5
config.h
@@ -1,6 +1,6 @@
|
||||
#define NO_SECTION 0
|
||||
#define FOUND_SECTION 10
|
||||
#define ERROR_STR 1
|
||||
#define ERROR_STR 1001
|
||||
#define ERROR_MAX_LEN 2
|
||||
#define NO_ERROR 0
|
||||
//ERROR DELIMITER
|
||||
@@ -24,6 +24,9 @@
|
||||
//LIMITS
|
||||
#define MAX_LEN_SECTIONNAME 128
|
||||
|
||||
//error parseConfig
|
||||
#define ERR_PARSECONFIG_UNKNOWN 201
|
||||
|
||||
struct configEntry
|
||||
{
|
||||
char *sectionName;
|
||||
|
||||
6
file.c
6
file.c
@@ -23,6 +23,8 @@ int getFile(char *fname, char **strContent,int cbSize,long *neededSize)
|
||||
{
|
||||
return FILE_ERROR_OPEN;
|
||||
}
|
||||
|
||||
printf("file openend:%s",fname);
|
||||
fseek(hfile,0,SEEK_END);
|
||||
file_size = ftell(hfile);
|
||||
if(strContent == NULL) //we must determine the size and return to neededSize
|
||||
@@ -53,8 +55,8 @@ int getFile(char *fname, char **strContent,int cbSize,long *neededSize)
|
||||
//buffer end-3 = last character
|
||||
printf("strcontent: %ld, [%c]\n",*neededSize,*(*strContent+ *neededSize-3));
|
||||
*(*strContent + *neededSize -1) ='\0';
|
||||
printf("after zero assign: %ld, %s\n",*neededSize,*(strContent+ *neededSize-1));
|
||||
printf("content:%s",*strContent);
|
||||
printf("after zero assign: %ld, %s\n",*neededSize,(*strContent+ *neededSize-1));
|
||||
//printf("content:%s",*strContent);
|
||||
fclose(hfile);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
59
test.c
59
test.c
@@ -1,4 +1,5 @@
|
||||
#include "config.h"
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -48,7 +49,7 @@ int main(void)
|
||||
}
|
||||
|
||||
long neededSize=0;
|
||||
if((ret=getFile("config.cfg",NULL,0,&neededSize))==NO_ERROR)
|
||||
if((ret=getFile("config-segfault.cfg",NULL,0,&neededSize))==NO_ERROR)
|
||||
{
|
||||
printf("sucessfull retrieved size:%ld\n",neededSize);
|
||||
}
|
||||
@@ -57,10 +58,17 @@ int main(void)
|
||||
return 1;
|
||||
}
|
||||
content = malloc(neededSize);
|
||||
memset(content,0,neededSize);
|
||||
if((ret=getFile("config.cfg",&content,neededSize,&neededSize))==NO_ERROR)
|
||||
printf("allocate buffer for filecontent size:%ld\n",neededSize);
|
||||
if(content == NULL)
|
||||
{
|
||||
printf("Sucessfull read file into buffer:%s|\n---\n",content);
|
||||
int error = errno;
|
||||
printf("MALLOC: %d\n",error);
|
||||
return error;
|
||||
}
|
||||
memset(content,0,neededSize);
|
||||
if((ret=getFile("config-segfault.cfg",&content,neededSize,&neededSize))==NO_ERROR)
|
||||
{
|
||||
//printf("Sucessfull read file into buffer:%s|\n---\n",content);
|
||||
}
|
||||
else {
|
||||
printf("Error on getFile:%d\n",ret);
|
||||
@@ -70,9 +78,46 @@ int main(void)
|
||||
struct configEntry *entry=NULL;
|
||||
int returnedCount=0;
|
||||
int i=0;
|
||||
int count=10;
|
||||
|
||||
entry = malloc(10*sizeof(struct configEntry));
|
||||
parseConfig(content,&entry,10*sizeof(struct configEntry),&returnedCount);
|
||||
entry = malloc(count*sizeof(struct configEntry));
|
||||
if(entry == NULL)
|
||||
{
|
||||
int error = errno;
|
||||
printf("MALLOC: %d\n",error);
|
||||
return 0;
|
||||
}
|
||||
ret = parseConfig(content,&entry,count,&returnedCount);
|
||||
if(ret!=NO_ERROR)
|
||||
{
|
||||
printf("Error on parseConfig:%d\nReallocate from size %d, to %d\n",ret,count,returnedCount);
|
||||
}
|
||||
if(returnedCount > count)
|
||||
{
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
free(entry[i].keyName);
|
||||
free(entry[i].keyValue);
|
||||
free(entry[i].sectionName);
|
||||
}
|
||||
|
||||
printf("Error on parseConfig:%d\nReallocate from size %d, to %d\n",ret,count,returnedCount);
|
||||
if((entry=realloc(entry,returnedCount*sizeof(struct configEntry)))==NULL)
|
||||
{
|
||||
printf("error could not reallocate from size %d to %d \n",count,returnedCount);
|
||||
return 1;
|
||||
}
|
||||
ret = parseConfig(content,&entry,returnedCount,&returnedCount);
|
||||
if(ret!=NO_ERROR)
|
||||
{
|
||||
printf("Error on parseConfig:%d\n",ret);
|
||||
return ret;
|
||||
}
|
||||
printf("returnedCount:%d\n",returnedCount);
|
||||
}
|
||||
|
||||
|
||||
|
||||
free(content);
|
||||
|
||||
for(i=0;i<returnedCount;i++)
|
||||
@@ -84,8 +129,6 @@ int main(void)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
free(keyValue);
|
||||
free(keyName);
|
||||
free(name);
|
||||
|
||||
Reference in New Issue
Block a user