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<stdio.h>
|
||||||
#include<stdlib.h>
|
#include<stdlib.h>
|
||||||
#include<string.h>
|
#include<string.h>
|
||||||
|
#include<errno.h>
|
||||||
/*
|
/*
|
||||||
* Here we check if the given string contains a section
|
* Here we check if the given string contains a section
|
||||||
* for example [SECTIONName] here delimiterLeft is [ and delimiterRight is ]
|
* 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;
|
return ERROR_STR;
|
||||||
}
|
}
|
||||||
int len = strlen(str);
|
int len = strlen(str);
|
||||||
printf("strlen: %d",len);
|
|
||||||
int state = ST_INIT;
|
int state = ST_INIT;
|
||||||
int leftDelimiterPos=0;
|
int leftDelimiterPos=0;
|
||||||
int rightDelimiterPos=0;
|
int rightDelimiterPos=0;
|
||||||
char *sectionName2 = NULL;
|
char *sectionName2 = NULL;
|
||||||
while(state != ST_FINISH)
|
while(state != ST_FINISH)
|
||||||
{
|
{
|
||||||
printf("STATE:%i\n",state);
|
|
||||||
switch(state)
|
switch(state)
|
||||||
{
|
{
|
||||||
case ST_INIT:
|
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)
|
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 i=fromPos; //character iterator, which starts from specified pos
|
||||||
int j=0; //the character iterator for the target string
|
int j=0; //the character iterator for the target string
|
||||||
int diffLen=toPos-fromPos;
|
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] = str[i];
|
||||||
}
|
}
|
||||||
ptr_name[j+1]='\0';
|
ptr_name[j+1]='\0';
|
||||||
//printf("*name:%s\n",ptr_name);
|
|
||||||
return NO_ERROR;
|
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)
|
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;
|
int state=ST_INIT;
|
||||||
char *ptr_name=*name;
|
char *ptr_name=*name;
|
||||||
char *ptr_value=*value;
|
char *ptr_value=*value;
|
||||||
@@ -159,11 +169,12 @@ int getNameValuePair(char *str,char leftDelimiterPos,char rightDelimiterPos,char
|
|||||||
return ERROR_DELIMITER_NOT_FOUND;
|
return ERROR_DELIMITER_NOT_FOUND;
|
||||||
}
|
}
|
||||||
posDelimiter = (ptrDelimiter - str);
|
posDelimiter = (ptrDelimiter - str);
|
||||||
printf("LenUntilDelimiter: %d",posDelimiter);
|
printf("LenUntilDelimiter: %d\n",posDelimiter);
|
||||||
if((ret=getStrAtPos(str,0,posDelimiter-1,&ptr_name,sizeName)) == NO_ERROR)
|
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 {
|
}else {
|
||||||
|
printf("Error at getStrAtPos:%d\n",ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if(rightDelimiterPos == 0)
|
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 state=ST_INIT;
|
||||||
int ret=0;
|
int ret=0;
|
||||||
int i=0;
|
int i=0;
|
||||||
|
*returnedCount=0;
|
||||||
char *sectionName=NULL;
|
char *sectionName=NULL;
|
||||||
struct configEntry *ptr_entry = *entry;
|
struct configEntry *ptr_entry = *entry;
|
||||||
char *keyName=NULL;
|
char *keyName=NULL;
|
||||||
char *keyValue=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);
|
sectionName = malloc(MAX_LEN_SECTIONNAME);
|
||||||
memset(sectionName,0,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");
|
token = strtok(buffer,"\n");
|
||||||
while(token != NULL && state != ST_FINISH)
|
while(token != NULL && state != ST_FINISH)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch(state)
|
switch(state)
|
||||||
{
|
{
|
||||||
case ST_INIT:
|
case ST_INIT:
|
||||||
printf("token(line): %s\n",token);
|
|
||||||
|
|
||||||
if((ret=checkSection(token,'[',']',§ionName))==FOUND_SECTION)
|
if((ret=checkSection(token,'[',']',§ionName))==FOUND_SECTION)
|
||||||
{
|
{
|
||||||
state = ST_FOUND_SECTION;
|
state = ST_FOUND_SECTION;
|
||||||
|
printf("FOUND_SECTION:%s\n",sectionName);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ST_FOUND_SECTION:
|
case ST_FOUND_SECTION:
|
||||||
keyName = malloc(MAX_LEN_SECTIONNAME);
|
keyName = malloc(MAX_LEN_SECTIONNAME);
|
||||||
keyValue = 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(keyName,0,MAX_LEN_SECTIONNAME);
|
||||||
memset(keyValue,0,MAX_LEN_SECTIONNAME);
|
memset(keyValue,0,MAX_LEN_SECTIONNAME);
|
||||||
if((ret=getNameValuePair(token,'=',0,
|
|
||||||
&keyName,&keyValue,
|
ret=getNameValuePair(token,'=',0,&keyName,&keyValue,MAX_LEN_SECTIONNAME,MAX_LEN_SECTIONNAME);
|
||||||
MAX_LEN_SECTIONNAME,MAX_LEN_SECTIONNAME
|
if(ret==NO_ERROR)
|
||||||
))==NO_ERROR)
|
|
||||||
{
|
{
|
||||||
ptr_entry[i].sectionName = strdup(sectionName);
|
printf("configSizeCount: %d, i:%d\n",configSizeCount,i);
|
||||||
ptr_entry[i].keyValue= strdup(keyValue);
|
if(i<configSizeCount)
|
||||||
ptr_entry[i].keyName = strdup(keyName);
|
|
||||||
free(keyName);
|
|
||||||
free(keyValue);
|
|
||||||
if(i<configSizeCount-1)
|
|
||||||
{
|
{
|
||||||
i++;
|
ptr_entry[i].sectionName = strdup(sectionName);
|
||||||
*returnedCount = i;
|
ptr_entry[i].keyValue= strdup(keyValue);
|
||||||
}
|
ptr_entry[i].keyName = strdup(keyName);
|
||||||
else {
|
|
||||||
free(sectionName);
|
|
||||||
return ERROR_STR;
|
|
||||||
}
|
}
|
||||||
|
i++;
|
||||||
|
*returnedCount = i;
|
||||||
state = ST_FOUND_SECTION;
|
state = ST_FOUND_SECTION;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
free(keyName);
|
|
||||||
free(keyValue);
|
|
||||||
state = ST_SKIP_READ;
|
state = ST_SKIP_READ;
|
||||||
}
|
}
|
||||||
|
free(keyName);
|
||||||
|
free(keyValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +284,11 @@ int parseConfig(char *buffer,struct configEntry **entry,int configSizeCount,int
|
|||||||
state = ST_INIT;
|
state = ST_INIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
printf("token: %s\n",token);
|
||||||
|
printf("buffer:%s\n--",buffer);
|
||||||
|
|
||||||
free(sectionName);
|
free(sectionName);
|
||||||
|
free(buffer);
|
||||||
|
printf("finish exitting parsing\nSTATE:%d\n",state);
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
99
config.cfg
99
config.cfg
@@ -1,66 +1,43 @@
|
|||||||
[PRINTER]
|
b=111
|
||||||
ip=192.168.209.173
|
1234567891
|
||||||
a=193
|
ip=192.168.209.173
|
||||||
b=111
|
[PRINTER1]
|
||||||
1234567891
|
a=1
|
||||||
ip=192.168.209.173
|
[PRINTER2]
|
||||||
[PRINTER]
|
b=2
|
||||||
[PRINTER]
|
[PRINTER3]
|
||||||
[PRINTER]
|
c=3
|
||||||
[PRINTER]
|
[PRINTER4]
|
||||||
[PRINTER]
|
d=4
|
||||||
[PRINTER]
|
[PRINTER5]
|
||||||
[PRINTER]
|
e=5
|
||||||
[PRINTER]
|
[PRINTER6]
|
||||||
[PRINTER]
|
f=6
|
||||||
[PRINTER]
|
[PRINTER7]
|
||||||
ip=192.168.209.173
|
g=7
|
||||||
a=193
|
[PRINTER8]
|
||||||
b=111
|
h=8
|
||||||
1234567891
|
[PRINTER9]
|
||||||
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
|
|
||||||
ip=192.168.209.173
|
ip=192.168.209.173
|
||||||
a=193
|
a=193
|
||||||
b=111
|
b=111
|
||||||
1234567891
|
1234567891
|
||||||
ip=192.168.209.173
|
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 NO_SECTION 0
|
||||||
#define FOUND_SECTION 10
|
#define FOUND_SECTION 10
|
||||||
#define ERROR_STR 1
|
#define ERROR_STR 1001
|
||||||
#define ERROR_MAX_LEN 2
|
#define ERROR_MAX_LEN 2
|
||||||
#define NO_ERROR 0
|
#define NO_ERROR 0
|
||||||
//ERROR DELIMITER
|
//ERROR DELIMITER
|
||||||
@@ -24,6 +24,9 @@
|
|||||||
//LIMITS
|
//LIMITS
|
||||||
#define MAX_LEN_SECTIONNAME 128
|
#define MAX_LEN_SECTIONNAME 128
|
||||||
|
|
||||||
|
//error parseConfig
|
||||||
|
#define ERR_PARSECONFIG_UNKNOWN 201
|
||||||
|
|
||||||
struct configEntry
|
struct configEntry
|
||||||
{
|
{
|
||||||
char *sectionName;
|
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;
|
return FILE_ERROR_OPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("file openend:%s",fname);
|
||||||
fseek(hfile,0,SEEK_END);
|
fseek(hfile,0,SEEK_END);
|
||||||
file_size = ftell(hfile);
|
file_size = ftell(hfile);
|
||||||
if(strContent == NULL) //we must determine the size and return to neededSize
|
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
|
//buffer end-3 = last character
|
||||||
printf("strcontent: %ld, [%c]\n",*neededSize,*(*strContent+ *neededSize-3));
|
printf("strcontent: %ld, [%c]\n",*neededSize,*(*strContent+ *neededSize-3));
|
||||||
*(*strContent + *neededSize -1) ='\0';
|
*(*strContent + *neededSize -1) ='\0';
|
||||||
printf("after zero assign: %ld, %s\n",*neededSize,*(strContent+ *neededSize-1));
|
printf("after zero assign: %ld, %s\n",*neededSize,(*strContent+ *neededSize-1));
|
||||||
printf("content:%s",*strContent);
|
//printf("content:%s",*strContent);
|
||||||
fclose(hfile);
|
fclose(hfile);
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
59
test.c
59
test.c
@@ -1,4 +1,5 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -48,7 +49,7 @@ int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
long neededSize=0;
|
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);
|
printf("sucessfull retrieved size:%ld\n",neededSize);
|
||||||
}
|
}
|
||||||
@@ -57,10 +58,17 @@ int main(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
content = malloc(neededSize);
|
content = malloc(neededSize);
|
||||||
memset(content,0,neededSize);
|
printf("allocate buffer for filecontent size:%ld\n",neededSize);
|
||||||
if((ret=getFile("config.cfg",&content,neededSize,&neededSize))==NO_ERROR)
|
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 {
|
else {
|
||||||
printf("Error on getFile:%d\n",ret);
|
printf("Error on getFile:%d\n",ret);
|
||||||
@@ -70,9 +78,46 @@ int main(void)
|
|||||||
struct configEntry *entry=NULL;
|
struct configEntry *entry=NULL;
|
||||||
int returnedCount=0;
|
int returnedCount=0;
|
||||||
int i=0;
|
int i=0;
|
||||||
|
int count=10;
|
||||||
|
|
||||||
entry = malloc(10*sizeof(struct configEntry));
|
entry = malloc(count*sizeof(struct configEntry));
|
||||||
parseConfig(content,&entry,10*sizeof(struct configEntry),&returnedCount);
|
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);
|
free(content);
|
||||||
|
|
||||||
for(i=0;i<returnedCount;i++)
|
for(i=0;i<returnedCount;i++)
|
||||||
@@ -84,8 +129,6 @@ int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
free(keyValue);
|
free(keyValue);
|
||||||
free(keyName);
|
free(keyName);
|
||||||
free(name);
|
free(name);
|
||||||
|
|||||||
Reference in New Issue
Block a user