ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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...
Well, I would first like to start by: asking where the segfault occurs, and any other information you have, as we are not going to debug your code for you.
Ok i still seem to have a problem.
I used malloc to get rid of the stack size problem, but now the code doesnt give the required output.
Fuction of the program is that program reads a rank from one file and divides the 'data' in the other file according to this rank...
I have highlighted in red the code where i made changes for the stack problem. I did get rid of the stack size problem , but there are warning during compile time.
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];
char **current_line;
int N = 1024;
current_line= (int **) malloc (sizeof (int *) * N);
/* 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;
}
The warning generated during compile time are
Code:
codem.c: In function āparse_input_fileā:
codem.c:281: warning: assignment from incompatible pointer type
codem.c:291: warning: passing argument 1 of āfgetsā from incompatible pointer type
codem.c:292: warning: passing argument 1 of āstrlenā from incompatible pointer type
codem.c:295: warning: passing argument 1 of āstrlenā from incompatible pointer type
codem.c:298: warning: comparison between pointer and integer
codem.c:298: warning: passing argument 1 of āvalueā from incompatible pointer type
codem.c:303: warning: passing argument 1 of āstrlenā from incompatible pointer type
codem.c:303: warning: passing argument 1 of āsend_file_outputā from incompatible pointer type
I made more few changes in the code, closing a file each time return-1 is exectued.Because apparently the code for data file with 8000 sequences wont work but would work prefectly fine for 6000 or so sequences.
I did this , coz there is a limitations to how many files can be opened.(correct me if i am wrong). Anyway, the problem got solved and the code is exectuted for 95% of the data.(previously it was just for 25% or so).But the program exits with segmentation fault.
Here is the gdb output from the code.There seeems to be a minor problem that i am not able to figure out.
Code:
Program received signal SIGSEGV, Segmentation fault.
0x0084cbfb in fclose@GLIBC_2.0 () from /lib/libc.so.6
(gdb) backtrace
#0 0x0084cbfb in fclose@GLIBC_2.0 () from /lib/libc.so.6
#1 0x007a1f71 in fclose@@GLIBC_2.1 () from /lib/libc.so.6
#2 0x08049403 in parse_input_file (fFile=0xbfd4b9d1 "seq") at codem.c:345
#3 0x0804948d in main (argc=3, argv=0xbfd49e34) at codem.c:363
(gdb) frame 3
#3 0x0804948d in main (argc=3, argv=0xbfd49e34) at codem.c:363
363 if (!parse_rank_file(argv[1])) parse_input_file(argv[2]);
(gdb) frame 0
#0 0x0084cbfb in fclose@GLIBC_2.0 () from /lib/libc.so.6
(gdb) frame 3
#3 0x0804948d in main (argc=3, argv=0xbfd49e34) at codem.c:363
363 if (!parse_rank_file(argv[1])) parse_input_file(argv[2]);
(gdb) frame 1
#1 0x007a1f71 in fclose@@GLIBC_2.1 () from /lib/libc.so.6
(gdb) frame 2
#2 0x08049403 in parse_input_file (fFile=0xbfd4b9d1 "seq") at codem.c:345
345 fclose(fFile);
(gdb) print buf
$1 = 0
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.