I'm trying to compile my c code, but I always get Segmentation fault after I execute my program. Here is part of my code:
LINE_LENGTH=300
struct clip {
int views;
char *user;
char *id;
char *title;
char *duration;
struct clip *next;
} *head;
my main function, where argv[1] is my csv file
int main(int argc, char **argv) {
int n;
head = build_a_lst(*(argv+1));
return 0;}
The rest of my code
struct clip *build_a_lst(char *fn) {
FILE *fp;
struct clip *hp;
char *fields[5];
char line[LINE_LENGTH];
int cnt=0,i;
hp=NULL;
fp=fopen(fn,"r");
if(fp=NULL)
exit(EXIT_FAILURE);
while(fgets(line,LINE_LENGTH,fp)!=NULL){
split_line(fields,line);//fields has five values stored
hp=append(hp,fields);
for(i=0;i<5;i++){
free(fields[i]);
fields[i]=NULL;
}
}
return hp;
}
void split_line(char **fields,char *line) {
int i=0;
char *token, *delim;
delim = ",\n";
token=strtok(line,delim);//ok line
for(;token!=NULL;i++){
fields[i]=malloc(strlen(token)+1);
strcpy(fields[i],token);
token=strtok(NULL,delim);
}
}
struct clip *append(struct clip *hp,char **five) {
struct clip *cp,*tp;
tp=malloc(sizeof(struct clip));
tp->views=atoi(five[1]);
tp->user=malloc(strlen(five[0]+1));
tp->duration=malloc(strlen(five[2]+1));
tp->id=malloc(strlen(five[3]+1));
tp->title=malloc(strlen(five[4]+1));
strcpy(tp->user,five[0]);
strcpy(tp->duration,five[2]);
strcpy(tp->id,five[3]);
strcpy(tp->title,five[4]);
cp=hp;
while(cp!=NULL)
cp=cp->next;
cp->next=tp;
hp=cp;
return hp;
}
According to some articles segmentation fault is caused by trying to read or write an illegal memory location. And since I am allocating memory in different parts of my code, the problem should be there. Can someone please help me with this. Thank you in advance.
There are some problems with your code:
if(fp=NULL) should be if(fp == NULL)
char *fields[5]; should be char *fields[5] = {NULL};
for(;token!=NULL;i++){ should be for(; token != NULL && i < 5; i++){
These:
tp->user=malloc(strlen(five[0]+1));
tp->duration=malloc(strlen(five[2]+1));
tp->id=malloc(strlen(five[3]+1));
tp->title=malloc(strlen(five[4]+1));
should be
tp -> user = malloc(strlen(five[0]) + 1);
tp -> duration = malloc(strlen(five[2]) + 1);
tp -> id = malloc(strlen(five[3]) + 1);
tp -> title = malloc(strlen(five[4]) + 1);
You don't free several of the malloced memory.
Related
There are quite a few topics on this subject but I haven't been able to find a solution that's worked for me; I am getting a segmentation fault whenever I try to change student_t.member->name. Below is the typedef structure that I am required to use:
typedef struct degree_t degree_t;
typedef struct student_t student_t;
struct degree_t {
student_t* member;
int course_id;
}
struct student_t {
char* name;
int age;
}
int main(int argc, char* argv[]) {
student_t *students = malloc(sizeof(student_t) * 3);
degree_t *degrees = malloc(sizeof(degree_t));
for (int i=0; i<3; i++) {
degrees[i].course_id = 1;
degrees[i].member->name = "Bob";
}
return 0;
}
I can change degrees[i].course_id perfectly fine, but whenever I try to change degrees[i].member -> name, I get a segmentation fault.
GDB indicates that this is a result of the line degrees[i].member->name = "Bob", but I'm don't understand why, and I don't know how to effectively change the value of degrees[i].member->name
Oops, you managed to place four errors in that small program.
The signature of main() should be main(int argc, char *argv[]). argv is an array of strings found on the command line.
You allocate memory for one degree, but in the for-loop you initialize three of them. This leads to a heap corruption.
You don't initialize degrees->member, but use it.
You allocate memory for three students, but don't use it.
Try this:
struct degree_t {
student_t* member;
int course_id;
}
struct student_t {
const char* name;
int age;
}
int main(int argc, char* argv[]) {
degree_t *degrees = malloc(3 * sizeof(degree_t));
for (int i=0; i<3; i++) {
degrees[i].course_id = 1;
degrees[i].member = malloc(sizeof(student_t));
degrees[i].member->name = "Bob";
degrees[i].member->age = 23;
}
return 0;
}
I have a data file of about 2500 lines. Each line contains 5 parameters. I declare a strut out side of a routine.
typedef struct data
{
char date[9];
char time[3];
float price;
float NAV;
float percent_change;
} _data ;
void readfile(int *j, struct data *input);
void readfile(int *j,struct data *input)
I set aside memory to read each line of the file into an array of structs.
input = calloc(days_of_data,sizeof(*input));
for (i = 0; i< days_of_data; i++)
input[i] = *(_data*)calloc(1,sizeof(_data));
and read the file.
while(fgets(line, 75, fp) != NULL)
{
date = strtok(line,",");
strcpy(input[i].date,date);
time = strtok(NULL,",");
strcpy(input[i].time, time);
price = strtok(NULL,",");
input[i].price = atof(price);
NAV = strtok(NULL,",");
input[i].NAV = atof(NAV);
percent_change = strtok(NULL,",");
input[i].percent_change = atof(percent_change);
i--;
}
This works. Now I want to sent the structure to the main program.
int main(int argc, const char * argv[]) {
struct data *input;
readfile(&j, input);
printf("%f\n",input[0].percent_change);
}
This compiles but crashes on the print statement.
You will have to use return value
struct data * readfile(int *j) {
struct data *input;
/* read the data */
return input;
}
int main(int argc, const char * argv[]) {
struct data *input;
input = readfile(&j);
printf("%f\n",input[0].percent_change);
}
or pointer
void readfile(int *j, struct data **input_out) {
struct data *input;
/* read the data */
*input_out = input;
}
int main(int argc, const char * argv[]) {
struct data *input;
readfile(&j, &input);
printf("%f\n",input[0].percent_change);
}
to pass the data to the caller.
I have written a program that reads in words from a text file. There is one word per line. I need to find how many times each word repeats. To find this out so far i have read the words in from the file and placed them all in a dynamically allocated array of struct. My problem is that the program keeps segmentation faulting whenever i try to run it. I assume there is a problem with how i am dynamically allocating the data.
Code is as follows;
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
//struct
struct _data {
char *word;
int number;
};
//scan for size of file
int SCAN(FILE *data) {
int size = 0;
char s_temp[50];
while (1) {
fscanf(data, "%s", s_temp);
if (feof(data)) break;
size++;
}
return size;
}
//load content into struct
int LOAD(FILE *data, int size, struct _data *Wordstruct){
int i;
char temp[50];
for (i=0; i <size; i++){
fscanf(data, "%s", temp , &Wordstruct[i].word, &Wordstruct[i].number);
Wordstruct[i].word =calloc(strlen(temp), sizeof(char));
strcpy(Wordstruct[i].word, temp);
if(strcasecmp(Wordstruct[i].word, temp) ==0){
Wordstruct[i].number++;
}
}
return size;
}
//count how many times each word repeats
void COUNT(struct _data *Wordstruct, int size){
int i;
int count;
count =0;
char *word;
if (strcasecmp(Wordstruct[i].word, word)==0){
count++;
for(i=0; i<size; i++){
printf("%s\n",Wordstruct[i].word,"occurs:\t",count);
}
}
}
//main routine
int main(int argc, char *argv[]){
int size;
FILE *data;
struct _data *Wordlist;
if(argc <2){
printf("Not enough arguments\n");
}
else{
FILE *data= fopen(argv[1],"r");
size =SCAN(data);
LOAD(data, size, Wordlist);
COUNT(Wordlist, size);
}
return 0;
}
You haven't allocated memory for Wordlist. Add
Wordlist = malloc(size*sizeof(*Wordlist));
before the call to LOAD.
And, as pointed out by #BLUEPIXY in comments, change
Wordstruct[i].word =calloc(strlen(temp), sizeof(char));
to
Wordstruct[i].word =calloc(strlen(temp)+1, sizeof(char));
Change this:
Wordstruct[i].word =calloc(strlen(temp), sizeof(char));
To this:
Wordstruct[i].word =calloc(strlen(temp)+1, sizeof(char));
You need to account for NULL terminator, strlen() does not do that for you here.
This is an incomplete code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define W 1031
#define B 256
struct FileCoordinates{
int x; /*line number*/
int y; /*word number*/
struct FileCoordinates *next;
};
struct FileStruct{
char *filename;
struct FileCoordinates *coordinates;
struct FileStruct *next;
};
struct WordStruct{
char *word;
struct WordStruct *left;
struct WordStruct *right;
struct FileStruct *files;
};
typedef struct FileCoordinates *CoorPtr;
typedef struct FileStruct *FilePtr;
typedef struct WordStruct *WordPtr;
WordPtr HashTable[W];
long int power(int a, long b){
long int pow, i;
pow = 1;
for (i = 0; i < b; i++){
pow = pow*a;
}
return pow;
}
int hashvalue (char *word){
long int i, value=0, n;
n = strlen(word);
for (i=0; i<n; i++){
value = value + power(B,n-i-1) * word[i];
}
return(value%W);
}
void putPosition(int x, int y, FilePtr *currfile){
CoorPtr currcors = (*currfile)->coordinates;
while (currcors!=NULL){
currcors = currcors->next;
}
currcors = (CoorPtr)malloc(sizeof(struct FileCoordinates));
currcors->x=x;
currcors->y=y;
}
void putFile(char *filename, WordPtr *currWord, int x, int y){
FilePtr currfile = (*currWord)->files;
while(currfile != NULL && strcmp(currfile->filename,filename)!=0){
currfile=currfile->next;
}
if (strcmp(currfile->filename,filename)==0){
putPosition(x, y, &currfile);
}
else{
currfile = (FilePtr)malloc(sizeof(struct FileStruct));
currfile->filename = filename;
putPosition(x, y, &currfile);
}
}
void insert(char *word, WordPtr *leaf, char *filename, int x, int y)
{
if( *leaf == NULL )
{
*leaf = (WordPtr) malloc( sizeof( struct WordStruct ) );
(*leaf)->word = word;
putFile(filename, &(*leaf), x, y);
/* initialize the children to null */
(*leaf)->left = 0;
(*leaf)->right = 0;
}
else if(word < (*leaf)->word)
{
insert( word, &(*leaf)->left, filename, x, y);
}
else if(word > (*leaf)->word)
{
insert( word, &(*leaf)->right, filename, x, y);
}
else if(word == (*leaf)->word){
putFile(filename, &(*leaf), x, y);
}
}
int main(int argc, char *argv[]){
int i, words, lines, value;
char *filename, *word, c;
FILE *fp;
word = (char *)malloc(21*sizeof(char));
if (argc<2){
perror("no files were inserted");
}
for (i=1; i<argc; i++){
words=1;
lines=1;
fp = fopen(argv[i], "r");
if (fp==NULL){
printf("Could not open file named %s! \n", argv[i]);
return 2;
}
filename = malloc( strlen( argv[i] ) + 1 );
strcpy( filename, argv[i] );
fscanf(fp, "%s", word);
value=hashvalue(word);
c=getc(fp);
insert(word, &HashTable[value], filename, lines, words);
if (c==' '){
words = words+1;
}
else if(c=='\n'){
lines=lines+1;
words=1;
}
}
system("PAUSE");
return 0;
}
And debugger gives me segmentation fault at this part:
while(currfile != NULL && strcmp(currfile->filename,filename)!=0){
currfile=currfile->next;
}
The reason of the code is to get text files as arguments, sort the words into binary trees placed in the hashtable and then by searching the keyword it shows you the coordinates it appears.
Anyway, i know this is a very novice code but im trying to understand.
You forget to set currfile->next to NULL when you create the object:
currfile = (FilePtr)malloc(sizeof(struct FileStruct));
currfile->filename = filename;
Reserve space with calloc instead of malloc, or add:
currfile->next = NULL;
Where do you initialize files? (Hint: you don't). This means it is an undefined value (not necessarily NULL). You need to initialize files before calling putFile.
As noted in the comment, once you fix that one, you need to do the same for next in both FileCoordinates and FileStruct and for coordinates in FileStruct.
Also as noted in the comments, you reuse the word buffer, meaning that all the nodes in the tree will have the same string. You should allocate a new buffer for the string when it is stored in the tree. Perhaps use strdup.
(*leaf)->word = strdup(word);
Once that is fixed, you also need to work on your string comparison. if(word == (*leaf)->word) compares the pointers, not their contents. You need to use strcmp if you want to compare the actual string data.
else if(strcmp(word, (*leaf)->word) == 0){
Hi I'm having trouble trying to initializing each element of the struct array. When I try and assign the value ZERO to both 'bSize' and 'msgs', it doesn't work as it errors out when i get to malloc. In the printf statement it prints a -1852803823 number. Excuse the messy code as i'm playing around trying to figure it out.
struct message{
int *data;
int bSize;
int msgs;
};
int main(int argc, char *argv[]) {
.....
}
void getSchedFile (FILE *file, int **schd) {
struct message sMsg[nodeCount];
const int pakSize = 6;
// Iniitialise message buffer
for (int i=0; i<nodeCount; i++){
sMsg[i].bSize = 0;
sMsg[i].msgs = 0;
printf("bSize %d\n",sMsg[i].bSize);
}
/* Get the number of bytes */
fseek(file, 0L, SEEK_SET);
int time;
while((fscanf(file, "%d", &time)) != EOF){
int src;
fscanf(file, "%d", &src); // get source node id
// These are here for easier reading code
int aPos = sMsg[src].bSize;
int nMsg = sMsg[src].msgs;
printf("size %d\n", sMsg[src].bSize);
if (sMsg[src].bSize==0){
sMsg[src].data = malloc( pakSize * sizeof(int));
}else{
sMsg[src].data = realloc(sMsg[src].data, (aPos+pakSize)*sizeof(int));
}
Where is the nodeCount value coming from? Is it a global variable? You should be very careful with global variables, and avoid using them if possible.
Pass the nodeCount in the method parameter and as Charlie mentioned, check it for > 0