how do I deal with this segmentation error - c

I keep receiving the same message "segmentation fault: 11"
gdb tells me that the break point is just after the main function. in the line where I declare the int j;
i really do not understand how can that possibly break the code.
the input this function reads is made up of simply 1 string followed by 2 numbers like
john 22 43 sam 11 23
all it's supposed to do is simply to store the entire input in "elenco" and then print the strings.
first i created a struct that matches the input.
then i made a function with the purpose of reading the input and store in a variable.
then i made a function whose variables is the output of the function that read the input ( so the input ) and that prints the strings given
can anybody help me identify the problem and solve it?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char name[20];
int distance;
int point;
} throw;
throw *read_file(FILE *f, int *j)
{
int i = 0;
int c;
int Dim = 32;
char buf[1000];
throw *list;
list = malloc(Dim *sizeof(*list));
if (list == NULL)
{
(*j) = 0;
return NULL;
}
while (fgets(buf, sizeof(buf), f)!= NULL)
{
sscanf(buf, "%19s %d %d",
list[*j].name,
&list[*j].distance,
&list[*j].point);
*j += 1;
if ( *j >= Dim)
{
Dim = Dim*2;
list = realloc(list, Dim *sizeof(*list));
if (list == NULL)
{
return NULL;
}
}
}
return list;
}
void print_everything(throw *list, int j)
{
int c;
for (c=0; c < j; c++ )
{
printf("%d\n",list[c].distance);
}
}
int main(int argc,const char *argcv[])
{
int j = 0;
FILE *file;
throw *list;
if (!( argc != 3))
{
printf("file's dimension is wrong\n");
return -1;
}
file = fopen(argcv[1], "r");
list = read_file(file, &j);
print_everything(list, j);
fclose(file);
return 0;
}
input1.txt
Mario 20 30
Giorgio 30 40
Mario 40 40
Davide 32 20
Mario 9 32
that is exactly what the file contained

Your program is fine. Your problem is in input1.txt , you need
Mario 20 30
Giorgio 30 40
Mario 40 40
Davide 32 20
Mario 9 32
Each line needs a \n as you read with fgets()

Made some changes on you code you are making the use of the lists wrong try to use pointers
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTR 250
typedef struct elenco
{
char *name;
int distance;
int point;
struct elenco *next;
} throw;
throw *list_add(throw *list, int distance, int point, const char *name)
{
throw *new = malloc(sizeof(throw));
if (new != NULL) {
new->distance = distance;
new->point = point;
new->name =(char*)malloc(strlen(name)+1);
strcpy(new->name,name);
new->next = list;
return new;
}
return list;
}
throw *read_file(FILE *f)
{
char buf[MAXSTR];
throw *list = malloc(sizeof(throw));
while (fgets(buf, sizeof(buf), f)!= NULL)
{
char name[MAXSTR];
int distance;
int point;
sscanf(buf, "%s %d %d",
name,
&distance,
&point);
list = list_add(list, distance, point, name);
}
return list;
}
void print_everything(throw *list)
{
while (list) {
printf("%d\n",list->distance);
list = list->next;
}
}
int main()
{
int argc;
const char *argcv;
FILE *file;
if (!( argc != 3))
{
printf("file's dimension is wrong\n");
return -1;
}
file = fopen(&argcv[1], "r");
throw *list = read_file(file);
print_everything(list);
fclose(file);
return 0;
}

Related

Unsure of how to store integers from a file to a struct in c

I created two structs to store values in.
struct pair {
int x_pos;
int y_pos;
};
struct coordinates_header {
int length;
struct pair data[1000];
};
typedef struct coordinates_header coordinates;
coordinates *coords;
I then try to store data from a file using
char line[max_read];
int x, y;
FILE *in_file = fopen(filename, "r");
int i = 0;
coordinates *new = (coordinates *)coords;
while (fgets(line,max_read,in_file) != NULL) {
sscanf(line,"%d %d", &x, &y);
new -> data[i].x_pos = x;
new -> data[i].y_pos = y;
i++;
}
new -> length = i;
Then I try to print out the values
int print_struct(void *coords) {
coordinates *new = (coordinates *)coords;
for (int i = 0; i < new -> length; i++) {
printf("%d, %d\n", new->data[i].x_pos, new->data[i].y_pos);
}
return 0;
}
And then I get a segmentation fault
I was wondering if someone could point out where the error is. I have no experience with void but require the flexibility for the structure in some functions I'm going to use.
The file read will have the form
100 30
50 200
.. ..
I believe their are some mistakes in your code:
Instead of using coordinates *coords;, which is just a dangling pointer not pointing anywhere in memory, you should just declare a structure member coordinates coords.
Their is no need for void* pointers in your code. You would be better off using coordinates *coords to access the address of the structure member coordinates coords, instead of void *coords.
You are not checking the return value of FILE *in_file, which could return NULL if not opened properly.
It is always good to check the result of sscanf(), just incase two x and y coordinates were not found on a line.
With these recommendations, you can write your code like this:
#include <stdio.h>
#include <stdlib.h>
#define NUMCOORDS 1000
#define MAXREAD 100
typedef struct {
int x_pos;
int y_pos;
} coords_t;
typedef struct {
coords_t coords[NUMCOORDS];
int length;
} coordinates_t;
void print_struct(coordinates_t *coordinates);
int main(void) {
coordinates_t coordinates;
char line[MAXREAD];
FILE *in_file;
int i = 0;
in_file = fopen("coords.txt", "r");
if (in_file == NULL) {
fprintf(stderr, "Error reading file.\n");
exit(EXIT_FAILURE);
}
while (fgets(line, MAXREAD, in_file) != NULL) {
if (sscanf(line, "%d %d", &coordinates.coords[i].x_pos,
&coordinates.coords[i].y_pos) != 2) {
fprintf(stderr, "two coordinates(x, y) not found.\n");
exit(EXIT_FAILURE);
}
i++;
}
coordinates.length = i;
print_struct(&coordinates);
fclose(in_file);
return 0;
}
void print_struct(coordinates_t *coordinates) {
int i;
for (i = 0; i < coordinates->length; i++) {
printf("%d, %d\n", coordinates->coords[i].x_pos, coordinates->coords[i].y_pos);
}
}

Structer pointer and pointer char array malloc array

I want to do structer array but I don't know structer array size therefore I need to use pointer structer and I want to do char array in the structer and I don't know char array size therefore I need to use pointer char in this structer but I don't understand malloc and realloc functions. How can I do this ?
#include <stdio.h>
#include <stdlib.h>
struct School{
char *school_name;
int student_size;
}*high_school;
void createSchool(struct School *s, char *schl_name, int student, int school_size)
{
int i = 0;
if(school_size == 1){
s = (struct School*) malloc(sizeof(struct School));
}
else{
s = (struct School*) realloc(s, (school_size*sizeof(struct School)));
}
(s+(school_size-1))->student_size = student;
(s+(school_size-1))->school_name = (char *) malloc(20); // 20 it is not important
(s+(school_size-1))->school_name = schl_name;
for(i; i<school_size; i++){
printf("%s\t%d\n",(s+i)->school_name, (s+i)->student_size);
}
printf("\n\n");
}
int main()
{
int i = 1;
createSchool(high_school, "Harvard", 50, i);
i++;
createSchool(high_school, "Oxford", 40, i);
i++;
createSchool(high_school, "MIT", 30, i);
}
I want to do screen shoot:
Harvard 50
Harvard 50
Oxford 40
Harvard 50
Oxford 40
MIT 30
but screen shoot of program :
Harvard 50
└1q 7405760
Oxford 40
7405760
(null) 0
MIT 30
Your pointer inside createSchool has local scope, so global pointer is not modified. Faster fix is to return new allocated memory back to caller.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct School{
char *school_name;
int student_size;
}*high_school;
struct School* createSchool(struct School *s, char *schl_name, int student, int school_size)
{
if(school_size == 1)
{
s = malloc(sizeof(struct School));
}
else
{
s = realloc(s, (school_size*sizeof(struct School)));
}
if (s != NULL)
{
s[school_size-1].student_size = student;
s[school_size-1].school_name = malloc(strlen(schl_name)+1);
strcpy(s[school_size-1].school_name, schl_name);
for(int i=0; i<school_size; i++)
{
printf("%s\t%d\n", s[i].school_name, s[i].student_size);
}
printf("\n\n");
}
return s;
}
int main(void)
{
int i = 1;
high_school = createSchool(high_school, "Harvard", 50, i);
i++;
high_school = createSchool(high_school, "Oxford", 40, i);
i++;
high_school = createSchool(high_school, "MIT", 30, i);
}
Minimal signature for main is int main (void)
Take note that malloc/realloc returned value have to be checked.
With your code, in case of realloc fails, you are loosing the pointer to the already allocated memory. So you should use a temp pointer to store the realloc result and check for integrity. After that you can reassign it ot your pointer.
struct School* createSchool(struct School *s, char *schl_name, int student, int school_size)
{
if(school_size == 1){
s = malloc(sizeof(struct School));
}
else
{
struct School *temp = realloc(s, (school_size*sizeof(struct School)));
if (temp == NULL)
return s;
s = temp;
}
if (s != NULL)
{
s[school_size-1].student_size = student;
s[school_size-1].school_name = malloc(strlen(schl_name)+1);
strcpy(s[school_size-1].school_name, schl_name);
for(int i=0; i<school_size; i++)
{
printf("%s\t%d\n", s[i].school_name, s[i].student_size);
}
printf("\n\n");
}
return s;
}
Different solution can be implemented using double pointer:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct School{
char *school_name;
int student_size;
}*high_school;
void createSchool(struct School **s, char *schl_name, int student, int school_size)
{
if(school_size == 1)
{
*s = malloc(sizeof(struct School));
}
else
{
struct School *temp = realloc(*s, (school_size*sizeof(struct School)));
if (temp == NULL)
return;
*s = temp;
}
if (*s != NULL)
{
(*s)[school_size-1].student_size = student;
(*s)[school_size-1].school_name = malloc(strlen(schl_name)+1);
strcpy((*s)[school_size-1].school_name, schl_name);
for(int i=0; i<school_size; i++)
{
printf("%s\t%d\n", (*s)[i].school_name, (*s)[i].student_size);
}
printf("\n\n");
}
}
int main(void)
{
int i = 1;
createSchool(&high_school, "Harvard", 50, i);
i++;
createSchool(&high_school, "Oxford", 40, i);
i++;
createSchool(&high_school, "MIT", 30, i);
}
Last thing take note that,to assign the name of school you can simply use:
(*s)[school_size-1].school_name = schl_name;

Hash Table - Sort Structure with qsort

Alright sorry for creating another question but the last one got overwhelmed and chaotic.
So I'm making a hash table which inserts words from a file (tokens) and after I have inserted them I need to sort them. The program template was given, the only functions that weren't complete were : insert_ht() , clear_ht() and compare. Even though I've done tons of search about qsort with compare, the program doesn't sort the frequencies (number of times each word was inserted) . I want em sorted from the highest to lowest.
Here is the code : "note that i shouldn't change any function except insert_ht() , clear_ht() and compare
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define HTABLE_SIZ 1001
#define MAX_LINE_SIZ 1024
/* Hash Table */
typedef struct node* link;
struct node { char *token; int freq; link next; };
link htable[HTABLE_SIZ] = { NULL }; /* Table of lists (#buckets) */
int size = 0; /* Size (number of elements) of hash table */
unsigned int hash (char *tok );
void insert_ht (char *data);
void clear_ht ( );
void print_ht ( );
void Process(FILE *fp);
int main(int argc, char *argv[])
{
int i;
FILE *fp;
printf("prin tin for \n");
for (i=1; i < argc; i++)
{
printf("prin tin fopen \n");
fp = fopen(argv[i],"r");
if (NULL == fp)
{
fprintf(stderr,"Problem opening file: %s\n",argv[i]);
continue;
}
printf("prin tin process \n");
Process(fp);
fclose(fp);
}
print_ht();
//clear_ht();
return 0;
}
void Process(FILE *fp)
{
const char *seperators = " ?!'\";,.:+-*&%(){}[]<>\\\t\n";
char line[MAX_LINE_SIZ];
char *s;
while((fgets(line,MAX_LINE_SIZ, fp)) != NULL)
{
for (s=strtok(line,seperators); s; s=strtok(NULL,seperators)){
printf("prin tin insert %s \n",s);
insert_ht(s);
}
}
}
/* Hash Function */
unsigned int hash(char *tok)
{
printf("bike stin hash \n");
unsigned int hv = 0;
while (*tok)
hv = (hv << 4) | toupper(*tok++);
printf("VGAINEIIIIIIIIIIIIII %d \n",hv);
return hv % HTABLE_SIZ;
}
void insert_ht(char *token)
{
printf("bike stin insert %s \n",token);
unsigned int hashval = hash(token);
struct node *new_list;
if (htable[hashval]==NULL){
printf("mesa stin prwti if %u %s \n",hashval,token);
//token = strdup(token);
new_list = malloc(sizeof(link));
new_list->token = strdup(token) ;
new_list->freq = 1;
new_list->next = htable[hashval];
htable[hashval] = new_list;
size++;
}else {
htable[hashval]->freq++;
}
printf("ta evale epitixws \n");
}
void clear_ht()
{
int i;
for(i=0; i<HTABLE_SIZ; i++) {
while(htable[i]->token!=NULL) {
htable[i]->token=NULL;
htable[i]->freq=NULL;
free(htable[i]);
}
}
}
int compare(const void *elem1, const void *elem2)
{
const struct node *p1 = elem1;
const struct node *p2 = elem2;
if (p1->freq > p2->freq)
return(+1);
else if (p1->freq < p2->freq)
return(-1);
else
return(0);
}
void print_ht()
{
int i, j=0;
link l, *vector = (link*) malloc(sizeof(link)*size);
for (i=0; i < HTABLE_SIZ; i++)
for (l=htable[i]; l; l=l->next)
vector[j++] = l;
qsort(vector,size,sizeof(link),compare);
for (i=0; i < size; i++)
printf("%-50s\t%7d\n",vector[i]->token,vector[i]->freq);
free(vector);
}
Ι found the solution. Apparently for some reason my compare function was wrong.
I still haven't figured out why but here is the correct one, hopefully someone else will find this post helpful!
int compare(const void *elem1, const void *elem2)
{
return (*(link*)elem2)->freq - (*(link*)elem1)->freq;
}

warning: implicit declaration of function TableCreate

I have to build a hash table data structure for this project, which I have done it in other files. For some reason when I compile my program and I get error, which is regarding initialization function (TableCreate();) of hash table. When I remove this part of the code from main function and execute, it works fine but then I get segfault when i try to add something to the hash table.
I believe my hash table code has nothing to do with this errors because my hash table code is based upon examples of Hash table code which was provided to us by our professor
I'm using GCC compiler.
Please help me solve this issue.
Error Message
src/sshell.c: In function âmainâ:
src/sshell.c:34: warning: implicit declaration of function âTableCreateâ
src/sshell.c:34: warning: assignment makes pointer from integer without a cast
sshell.c
#include "parser.h"
#include "shell.h"
#include "hash_table.h"
#include "variables.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(void){
char input[1000], sInput[1000]; // String to get user input
int count=1, len; // num=0;
struct Table *t;
t = TableCreate(); //create the table
int while_track;
FILE *ptr_file;
ptr_file =fopen(".simpleshell_history","a");
fclose(ptr_file);
printf("\nWelcome to the sample shell! You may enter commands here, one\n");
printf("per line. When you're finished, press Ctrl+D on a line by\n");
printf("itself. I understand basic commands and arguments separated by\n");
printf("spaces, redirection with < and >, up to two commands joined\n");
printf("by a pipe, tilde expansion, and background commands with &.\n\n");
printf("\npssh$ ");
while (fgets(input, sizeof(input), stdin)) {
strcpy(sInput, input);
len = strlen(input);
if( input[len-1] == '\n' ){
input[len-1] = '\0';
}
while_track = 1; // used to keep track of loop
while (while_track == 1){
count+=1;
if (strcmp(input, "history")==0){
while_track = History(); // print history function call
}else if (strcmp(input, "!!")==0){
while_track = Previous(input); // execute previous function call
}else if (strncmp(input, "!",1)==0){ // !string and !number sort
if(isdigit(input[1])){
while_track = Number(input);
} else {
while_track = String(input);
}
}else { // if the user entry was not any of specfic comnnad then pass the command to parse to execute
other(input,t);
parse(input);
while_track = 0;
}
}
HistoryFile(sInput); // A function call to recode commands entered by the user into a file
printf("\npssh$ ");
}
return 0;
}
hash_table.c
#include "hash_table.h"
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
void feedData(char * var, char * val, struct Table *t){
//const char * key=0;
printf("\n In FeedData Function\n");
Table_add(t, var, val);
printf("\nInside Feed Function -- Veriable: %s Value: %s\n",var, val);
}
unsigned int hash(const char *x) {
printf("\n In Hash\n");
int i;
unsigned int h = 0U;
printf("\n In Hash - Before for loop\n");
for (i=0; x[i]!='\0'; i++)
printf("\n In Hash - In for loop %d \n", i);
h = h * 65599 + (unsigned char)x[i];
printf("\n In Hash - In for loop - after calculation \n");
unsigned int g;
g = h % 1024;
printf("\n In Hash - In for loop - before return: %u \n",g);
return g;
}
struct Table *Table_create(void) {
printf("\n In Table_create\n");
struct Table *t;
t = (struct Table*)calloc(1, sizeof(struct Table));
return t;
}
void Table_add(struct Table *t, const char *key, char * val){
printf("\n In Table_add\n");
struct Node *p = (struct Node*)malloc(sizeof(struct Node));
int h = hash(key);
printf("\n In Table_add - after hash key\n");
//p->key = *key;
strcpy(p->key,key);
printf("\n In Table_add - after first key\n");
strcpy(p->value,val);
printf("\n In Table_add - after Value\n");
p->next = t->array[h];
printf("\n In Table_add - after p->next\n");
t->array[h] = p;
printf("\n In Table_add - after t->array[h] = p\n");
}
/*
int Table_search(struct Table *t, const char *key, int *value){
struct Node *p;
int h = hash(key); //---------------------------------------------------------------------
for (p = t->array[h]; p != NULL; p = p->next)
if (strcmp(p->key, key) == 0) {
*value = p->value;
return 1;
}
return 0;
}
*/
/*
void Table_free(struct Table *t) {
struct Node *p;
struct Node *nextp;
int b;
for (b = 0; b < BUCKET_COUNT; b++)
for (p = t->array[b]; p != NULL; p = nextp) {
nextp = p->next;
free(p);
}
free(t);
}
*/
hash_table.h file code
#ifndef HASH_TABLE_H
#define HASH_TABLE_H
struct Table *Table_create(void);
void Table_add(struct Table *t, const char *key, char * val);
unsigned int hash(const char *x);
void feedData(char * var, char * val, struct Table *t);
enum {BUCKET_COUNT = 1024};
struct Node {
char key[1000];
char variable[1000];
char value[1000];
struct Node *next;
};
struct Table {
struct Node *array[BUCKET_COUNT];
};
#endif
Warning 1: You are calling TableCreate while your function name is Table_create
Warning 2: After looking at new identifier followed by (, compiler assumes it is a function that takes variable number of arguments and returns int.

Array of Structs strange output?

Can anyone give me some indication as to why array of structs doesn't print out properly ?
I think its something to do with the memory I have allocated to the struct I am unsure !!
Using mac osx mountain lion xcode 4 gcc
Thanks for any help completely stuck!!
(Please have patience I am only a student !)
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
typedef struct{
char* one;
char* two;
} Node;
Node *nodes;
int count = 0;
//-----------------------------------------------------------------------
void add(char *one,char*two){
char x[40];
char y[40];
printf("reached..\n");
strcpy(x,one);
strcpy(y,two);
printf("--> X: %s\n",x);
printf("--> Y: %s\n",y);
Node newNode;
newNode.one = x;
newNode.two = y;
nodes[count]= newNode;
count++;
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void print(){
int x;
for (x = 0; x < 10; x++)
{
printf("%d : (%s, %s) \n",x,nodes[x].one, nodes[x].two);
}
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void check(char **arg)
{
if(strcmp(*arg, "Add") == 0)
{
add(arg[1],arg[2]);
}else if(strcmp(*arg,"print") == 0)
{
print();
}else{
printf("Error syntax Enter either: \n Add [item1][item2]\n OR \n print\n");
}
}
//-----------------------------------------------------------------------
void readandParseInput(char *line,char **arg)
{
if (fgets (line, 512, stdin)!= NULL) {
char * pch;
pch = strtok (line," \n\t");
int count = 0;
arg[0] = pch;
while (pch != NULL)
{
count++;
pch = strtok (NULL, " \n\t");
arg[count] =pch;
}
}else{
printf("\n");
exit(0);
}
}
//-----------------------------------------------------------------------
int main()
{
int size = 100;
nodes = calloc(size, sizeof(Node));
int i;
for(i = 0;i <100; i++){
printf("%s , %s \n",nodes[i].one,nodes[i].two );
// nodes[i].one = ".";
// nodes[i].two = ".";
}
char line[512]; /* the input line */
char *arg[50]; /* the command line argument */
while (1)
{
readandParseInput(line,arg);
if(arg[0] != NULL){
check(arg);
}
}
return(0);
}
You're keeping pointers to the following automatic variables:
char x[40];
char y[40];
These go out of scope when add() returns, leaving you with dangling pointers.
You either have to turn Node::one and Node::two into arrays, or allocate memory for them on the heap.
In you add() function, you cannot assign one struct to another via an = operator... you would have to copy it...
memcpy( &nodes[count], &newNode )
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *fn;
}NAME;
#define NAME_LEN 20
int main()
{
NAME name;
name.fn = (char *) calloc(NAME_LEN, sizeof(char));
strcpy(name.fn, "Namco");
printf("Name: %s\n", name.fn);
free(name.fn);
return 0;
}
you can't just assign a string like this in c
newNode.one = x;
newNode.two = y;
what is newNode.one referring to???
at Function add
newNode.one = x;
newNode.two = y;
to
newNode.one = strdup(x);
newNode.two = strdup(y);

Resources