Segmentation fault
Hello All,
I have written a code in C and it runs fine for small to moderate data sets.However, when i run the code for large data sets, i get segmentation fault during execution.How can i fix this??
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static double boundry[40]={0};
/* a struct to hold rank data, to be made into a linked list */
struct rank_spec
{
char *section;
double value;
struct rank_spec *next_spec;
};
/* a linked list pointer for our list of rankings */
static struct rank_spec *rank_list = 0;
/* a rank file parser which assembles the linked list */
static int parse_rank_file(const char *fFile)
{
/* this keeps us from parsing more than one rank file */
if (rank_list) return -1;
/* open the file provided */
FILE *rank_file = fopen(fFile, "r");
if (!rank_file) return -1;
/* this is to hold input data from the file */
char current_line[1024];
/* this will give us a reference to the end of the linked list */
struct rank_spec *current = rank_list;
while (!feof(rank_file))
/* this loop parses one line of the file at a time */
{
/* if there are less than 3 characters, the line is ignored ('\n' + '\0' = 2) */
if (!fgets(current_line, 1024, rank_file)) break;
if (strlen(current_line) < 3) continue;
double value = 0;
/* determine where the ':' character is */
int position = strlen(current_line);
while (--position && current_line[position] != ':');
if (position <= 0) return -1;
/* convert the right side to a long integer */
value = strtod(current_line + position + 1, 0);
/* changing the delimeter effectively truncates the string */
current_line[position] = 0;
/* if this is the first element, put it in 'rank_list', otherwise 'current->next_spec' */
if (!rank_list) rank_list = current = malloc(sizeof(struct rank_spec));
else if (current) current->next_spec = malloc(sizeof(struct rank_spec));
else return -1;
/* if we couldn't make a new element then return */
if (!current->next_spec && !current) return -1;
/* if we happened to make other than the first one, copy the pointer to 'current' so we can use it */
if (current->next_spec) current = current->next_spec;
/* allocate a space for the label within the element */
current->section = malloc(position + 1);
/* copy the label to the element and set its value */
strcpy(current->section, current_line);
current->value = value;
/* to make sure we don't have memory leaks, show what we've done */
printf("new rank added: %s = %f\n", current->section, current->value);
}
return 0;
}
/* every allocation function needs one to clean up */
static void clean_up()
{
struct rank_spec *old = 0;
while (rank_list)
/* this loop frees the label string then the element until the list is empty */
{
/* to make sure we don't have memory leaks, show what we've done */
printf("removing rank: %s = %f\n", rank_list->section, rank_list->value);
old = rank_list;
rank_list = rank_list->next_spec;
free(old->section);
free(old);
}
}
/* this function will search the linked list for the correct value */
static double value(const char *rRank)
{
struct rank_spec *current = rank_list;
/* this loop compares each element label with the one needed until one is found */
while (current && strcmp(rRank, current->section)) current = current->next_spec;
if (!current) return -1;
else return current->value;
}
///////////////////////////////////////////////////////////////////////////////////
//getting the file that has the bucket boundries
static double boundryfile(const char *fFile)
{
FILE *boundry_file = fopen(fFile, "r");
double elapsed_seconds;
char line[80];
int count=0;
while(fgets(line, 80, boundry_file) != NULL)
{
/* get a line, up to 80 chars from fr. done if NULL */
sscanf (line, "%lf",&elapsed_seconds);
/* convert the string to a long int */
printf ("%lf\n", elapsed_seconds);
boundry[count]=elapsed_seconds;
count=count+1;
//printf("And this comes from the array boundry: %f",boundry[count]);
}
}
/////////////////////////////////////////////////////////////////////////////////
/* makes opening files a little easier */
#define total_files 16
static const char *file_names[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16" };
/* this is ALMOST the same function as before, but not quite */
static int send_file_output(const char *dData, unsigned int sSize, int fFile)
/* supply: output data, output size, and destination file (1-10, 0 to clean up, < 0 to ignore) */
{
static int initialized = 0;
static FILE *output_files[ total_files ];
if (!initialized)
/* initialize the output file streams */
{
int I;
for (I = 0; I < total_files; I++) output_files[I] = fopen(file_names[I], "w");
initialized = 1;
}
if (fFile == 0)
/* close the output file streams (called using file 0) */
{
int I;
for (I = 0; I < total_files; I++)
{
if (initialized && output_files[I]) fclose( output_files[I] );
output_files[I] = (FILE*) 0;
}
initialized = 0;
}
/* actually process the output */
if (fFile > total_files || fFile < 1) return -1;
if (!output_files[ fFile - 1 ]) return -1;
return fwrite(dData, 1, sSize, output_files[ fFile - 1 ]);
}
/* since the ranks don't necessarily correspond to the file name, this converts them */
static double determine_file(double vValue)
{
/* for simplicity, the rank equals the file name */
double yy;
yy=boundryfile("bucketboundry");
printf("%f",boundry[0]);
printf("%f",boundry[1]);
printf("%f",boundry[2]);
if(boundry[4]==0){
if (vValue < 0.0) return -1;
else if (vValue <= boundry[0]) return 1;
else if (vValue <= boundry[1]) return 2;
else if (vValue <= boundry[2]) return 3;
else if (vValue > boundry[2]) return 4;
else return -1;
}else if(boundry[8]==0){
if (vValue < 0.0) return -1;
else if (vValue <= boundry[0]) return 1;
else if (vValue <= boundry[1]) return 2;
else if (vValue <= boundry[2]) return 3;
else if (vValue <= boundry[3]) return 4;
else if (vValue <= boundry[4]) return 5;
else if (vValue <= boundry[5]) return 6;
else if (vValue <= boundry[6]) return 7;
else if (vValue > boundry[6]) return 8;
else return -1;
}else if(boundry[12]==0){
if (vValue < 0.0) return -1;
else if (vValue <= boundry[0]) return 1;
else if (vValue <= boundry[1]) return 2;
else if (vValue <= boundry[2]) return 3;
else if (vValue <= boundry[3]) return 4;
else if (vValue <= boundry[4]) return 5;
else if (vValue <= boundry[5]) return 6;
else if (vValue <= boundry[6]) return 7;
else if (vValue <= boundry[7]) return 8;
else if (vValue <= boundry[8]) return 9;
else if (vValue <= boundry[9]) return 10;
else if (vValue <= boundry[10]) return 11;
else if (vValue > boundry[10]) return 12;
else return -1;
}else{
if (vValue < 0.0) return -1;
else if (vValue <= boundry[0]) return 1;
else if (vValue <= boundry[1]) return 2;
else if (vValue <= boundry[2]) return 3;
else if (vValue <= boundry[3]) return 4;
else if (vValue <= boundry[4]) return 5;
else if (vValue <= boundry[5]) return 6;
else if (vValue <= boundry[6]) return 7;
else if (vValue <= boundry[7]) return 8;
else if (vValue <= boundry[8]) return 9;
else if (vValue <= boundry[9]) return 10;
else if (vValue <= boundry[10]) return 11;
else if (vValue <= boundry[11]) return 12;
else if (vValue <= boundry[12]) return 13;
else if (vValue <= boundry[13]) return 14;
else if (vValue <= boundry[14]) return 15;
else if (vValue > boundry[14]) return 16;
else return -1;
}
}
/* this is the function to parse the input data */
static int parse_input_file(const char *fFile)
{
/* open the file provided */
FILE *input_file = fopen(fFile, "r");
if (!input_file) return -1;
/* this is to hold input data from the file */
char current_line[1024];
/* indicator of the current file */
int current_file = -1;
while (!feof(input_file))
/* this loop keeps reading lines from the file until it reaches the end */
{
/* if there are less than 3 characters, the line is ignored ('\n' + '\0' = 2) */
if (!fgets(current_line, 1024, input_file)) break;
if (strlen(current_line) < 3) continue;
/* to allow comparison to the list, remove the newline */
current_line[strlen(current_line) - 1] = 0;
/* if the line denotes a label, find the correct file and change it */
if (current_line[0] == '>') current_file = determine_file(value(current_line + 1));
/* else*/
/* otherwise, send the output to the file and replace the newline */
/* {*/
send_file_output(current_line, strlen(current_line), current_file);
send_file_output("\n", 1, current_file);
/* }*/
}
return 0;
}
/* the main function */
int main(int argc, char *argv[])
{
if (argc != 3)
{
printf("%s [rank file] [input file]\n", argv[0]);
return -1;
}
/* parse both files */
if (!parse_rank_file(argv[1])) parse_input_file(argv[2]);
/* clean things up */
clean_up();
send_file_output(0, 0, 0);
return 0;
}
Any help would be highly appreciable.Thanks in advance...:)
|