I am using this function:
int times_on_table(char *search,struct table index[],int wct){
int ct=0,num=0;
while(ct<wct){
if(strcmp(search,(index[ct].label))==0) {
num++;
}
ct++;
}
return num;
}
to search through an array of structs and find all the times a certain string is stored in the array and returns the number of times the string occurs. Whenever i use this function inside main:
/*EDIT: i had a main from the wrong program my apologies*/
int main(int argc, char **argv){
int numwds=get_num_words(argv[1]);
struct table index[numwds];
int a;
struct cmd_ops symbol[22];
store(argv[1],index,numwds);
ops_gen(symbol);
int b=times_on_table("in",index,numwds);
printf("%d",b);
}
the code works fine. However, when i try to use it inside certain functions like this one
struct table* store(char *filename,struct table index[]) {
FILE *fp;
fp=fopen(filename,"r");
char *a;int d=0,e=0,t=0;
a=malloc(60);
int wordcount=get_num_words(filename);
while(d<wordcount){
fscanf(fp,"%s",a);
if ((index[d].label=strdup(a))==NULL)
break;
index[d].word_num=d;
times_on_table("this",index,wordcount);/*when i comment this out
of my code it runs fine*/
index[d].address=findline(filename,index[d].label,wordcount,index,t);
d++;
}
free(a);
}
the code does not run and gives me a segmentation fault. Any thoughts?
EDIT: I don't know if this helps but when i get the segfault, it happens before even the first line of code in main is executed.
EDIT:here is the other function that causes a segfault when times_on_table() is called:
int findline(char *filename,char *check,int wordcount,struct table index[],int t){
char *a;
a=malloc(60);
int b=line_count(filename);
int ch;
fpos_t pos;
int line=0,wd=0,loc,s=0,c=1,times;
times=times_on_table(check,index,wordcount);
FILE *fp;
fp=fopen(filename,"r");
int list[wordcount];
while(c<=b){
fscanf(fp,"%s",a);
fgetpos(fp,&pos);
ch=fgetc(fp);ch=fgetc(fp);
if(strcmp(a,check)==0){
if(times==0)
return line;
else
times--;
}
if(ch==10){
line++;c++;
}
else
fsetpos(fp,&pos);
}
return line;
}
it was in this function that i first added times_on_table(), and had the segmentation fault keep my program from running.
Here
while(d<wordcount){
fscanf(fp,"%s",a);
if ((index[d].label=strdup(a))==NULL)
break;
index[d].word_num=d;
times_on_table("this",index,wordcount);
you try to count the occurrences of "this" in a wordcount long array, but you have only filled d+1 slots of the array. The other slots may contain garbage, and then accessing index[ct].label is likely to cause a segmentation fault when ct > d.
It is very likely you are going past the array index. These two lines do not really match up (from the code you have shared with us :
int wordcount=get_num_words(filename);
times_on_table("this",index,wordcount);
(wordcount I assume counts something in filename which is passed in as the first parameter, but it seems irrelevant to your struct table index[])
So the parameter being passed in struct table index[], is probably a different size than the value you are storing into wordcount. I would suggest you pass in the array size as a parameter to the store function and use that as you would in your working main example. example
struct table* store(char *filename,struct table index[], int structSize){
....
times_on_table("this",index,structSize); //replace b from the call in main
}
It may be related with setting the "index[d].label" properly. Try to print all the labels outside the times_on_table() function without comparing them with anything.
Related
I want to order an array of structs by the first letter of a student´s name. The code that I made so far is the following:
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int cod;
char* name;
int mark;
}student;
void print(student* class){
int i;
for (i=0;i<4;i++){
printf("%d\n",class[i].cod);
printf("%s\n",class[i].name);
printf("%d\n",class[i].mark);
printf("\n");
}
}
int main(int argc, char *argv[])
{
int ind,i;
int cod=1000;
student class[4];
student temp;
int lengthData=10;
for (i=0;i<4;i++)
{
class[i].name=malloc(sizeof(char)*lengthData);
}
class[0].cod=cod;
class[0].name="Joseph";
class[0].mark=15;
cod++;
class[1].cod=cod;
class[1].name="Jonathan";
class[1].mark=16;
cod++;
class[2].cod=cod;
class[2].name="Karen";
class[2].mark=17;
cod++;
class[3].cod=cod;
class[3].name="Anna";
class[3].mark=20;
print(class);
for (ind=1;ind<4;ind++){
temp=class[ind];
i=ind-1;
while (i>=0){
if (temp.name[0]<class[i].name[0]){
class[i+1]=class[i];
class[i]=temp;
i--;
}
else break;
}
}
printf("ordered data\n");
print(class);
system("PAUSE");
return 0;
}
I am using DevC++ and when I run it the program hangs, but when I add the following lines before the loop for the bubble sort (only for testing):
class[3]=class[2];
printf("%s\n",class[3].name);
for (ind=1;ind<4;ind++){
...
The program works even though one record (3) has been replaced by the data of record (2).
Any help?
You have quite a few problems:
First of all you leak memory, since you allocate memory and make name point to that, then you make name point somewhere else. You need to copyinto the memory you allocate.
Secondly, also with the name member, once you copy into the memory, you will go out of bounds since you only allocate five bytes for each string, but you have strings of up to at least nine characters (ten with the terminator).
Thirdly, and more about going out of bounds, your class array only have three elements, yet you access four elements of the array.
The reassignment of the name pointer won't cause more problems than a temporary memory leak, since you don't attempt to pass the pointer to free. The second problem isn't really an issue because you don't copy the strings yet. The third problem on the other hand, that will lead to undefined behavior as soon as you execute that code.
I'm a bit confused with memory allocation.
I want to fill a structure Sudoku with random number and then check if a box of 9 numbers are correct.
#define SUDOKU_SIZE 9
typedef struct
{
int grid[SUDOKU_SIZE][SUDOKU_SIZE];
} sudoku_t;
int main(int argc, char const *argv[]){
sudoku_t *s=malloc(sizeof s);
s->grid[0][0]=6;//manualy setting the value of the sudoku
...
s->grid[8][8]=7;
fill_sudoku_test(s);//fill s, a feasible Sudoku with random number
int k, l;
for(k=0;k<SUDOKU_SIZE;k+=3){
for(l=0;l<SUDOKU_SIZE;l+=3){
if(correct_box(s,k,l))//check if a box of 3 by 3 contains 9 differents numbers
printf("Box correct at position :%d and %d\n",k,l);
}
}
free(s);
return EXIT_SUCCESS;
}
When I compile this code, I got a core dumped error.
If somebody got a solution, I'm interested
EDIT
Here's the others functions :
void fill_sudoku_test(sudoku_t *s){
int k, l;
time_t t;
srand((unsigned) time(&t));
for(k=0;k<SUDOKU_SIZE;k++){
for(l=0;l<SUDOKU_SIZE;l++){
if(!(s->grid[k][l])) {
s->grid[k][l]=rand()%SUDOKU_SIZE+1;
}
}
}
}
int correct_tab(int value[]){
int i;
int tab[9];
for(i=0;i<SUDOKU_SIZE;i++){
tab[i]=0;
}
for(i=0;i<SUDOKU_SIZE;i++){
if(tab[value[i]-1]==1){
return 0;
}
else{
tab[value[i]-1]=1;
}
}
return 1;
}
int correct_box(sudoku_t *s, int i, int j){
int tab[SUDOKU_SIZE];
int count=0;
int k,l;
for(k=0;k<3;k++){
for(l=0;l<3;l++){
tab[count]=s->grid[i+k][j+l];
}
}
return (correct_tab(tab));
}
sudoku_t *s=malloc(sizeof s);
should be
sudoku_t *s=malloc(sizeof(sudoku_t));
or
sudoku_t *s=malloc(sizeof(*s));
EDIT
in function correct_tab the value[i] can be (and is) 0. Then:
tab[value[i]-1]=1;
and
if(tab[value[i]-1]==1)
access the array out of bounds.
EDIT 2
In correct_tab value array is not intited for the whole SUDOKU_SIZE then some values of array are undefined.
You can, at least, declare it as:
int tab[SUDOKU_SIZE] = {0};
EDIT3
To answer to your comments:
Your init is correct: init numbers are between 1 to 9.
The problem is that correct_tab is called from correct_box is passing tab, a local (stack allocated) array. This means 1 main thing:
its values are not itited to 0. Those value are randoms due to the
stack allocation.
using my EDIT2 code you can set 0 for all values of the array.
BTW your correct_tab function loops the whole tab array, where only some values are extracted from your sudocu_t struct matrix.
This happend due to:
count variable into correct_box function is always 0. You must inc it each time you set a value into tab array.
You should pass the count value to correct_tab function to allow to loop on the real inserted values only.
When you allocate:
sudoku_t *s=malloc(sizeof s);
This only allocates memory sufficient to store a pointer. You probably mean:
sudoku_t *s=malloc(sizeof(*s));
Beyond that, you will need to use a debugger to identify which part of the code actually triggered the segmentation fault.
First problem lies in this line:
sudoku_t *s=malloc(sizeof s);
which means malloc is allocating memory equal to the size of pointer, which could be 4 bytes or 8 bytes depending on the machine.
Ideally what u r expecting is allocating the size of structure, so this should be:
sudoku_t *s = (sudoku_t *) malloc(sizeof(sudoku_t));
Hello in first I will give some details, I' m working in:
Ubuntu , in c language and my compiler is gcc.
I was make a lisle test of my skills because I'm not so good with pointers so I tried my luck and I get a weird output.
I will show my code now.
#include<stdio.h>
#include<string.h>
#define F1 ".file.txt"
typedef struct{
char par1[30];
int par2;
int par3;
int par4;
char* par5[3];
}S1;
//this was the structure I was working
void initiate_S1(S1*a,char part1[],int* part2,int *part3, int*part4,char part51[],char part52[],char part53[]);
//this function will start the struct parameters
void get_S1(S1*a);
//this function will print struct parameters
void save_S1_on_file(S1*a);
//this will save all parameters of a structure in file
void search_S1_on_file(S1*a);
//This function will search for a first parameter of structure and if
//find it fill the other parameters
int main(){
S1 a;
int part2,part3,part4;
char part1[30],part51[15],part52[15],part53[15];
scanf("%s %d %d %d %s %s %s",part1,&part2,&part3,&part4,part51,part52,part53);
initiate_S1(&a,part1,&part2,&part3,&part4,part51,part52,part53);
get_S1(&a);
save_S1_on_file(&a);
search_S1_on_file(&a);
get_S1(&a);
return 0;
}
//this main is only to test the functions
void initiate_S1(S1*a,char part1[],int* part2,int *part3, int*part4,char part51[],char part52[],char part53[]){
strcpy(a->par1,part1);
a->par2=*part2;
a->par3=*part3;
a->par4=*part4;
a->par5[0]=part51;
a->par5[1]=part52;
a->par5[2]=part53;
}
void get_S1(S1*a){
printf("%s\n%d\n%d\n%d\n%s %s %s\n",a->par1,a->par2,a->par3,a->par4,a->par5[0],a->par5[1],a->par5[2]);
}
void save_S1_on_file(S1*a){
FILE *af;
af=fopen(F1,"a");
fprintf(af,"%s;%d;%d;%d;%s;%s;%s;\n",a->par1,a->par2,a->par3,a->par4,a->par5[0],a->par5[1],a->par5[2]);
fclose(af);
}
void search_S1_on_file(S1*a){
FILE *af;
char s[100];
char*token;
af=fopen(F1,"r");
int n=2;
while(fgets(s,100,af)!=NULL){
token=strtok(s,";");
if(strstr(a->par1,token)!=NULL){
n=0;
token=strtok(NULL,";");
a->par2=atoi(token);
token=strtok(NULL,";");
a->par3=atoi(token);
token=strtok(NULL,";");
a->par4=atoi(token);
a->par5[0]=strtok(NULL,";");
a->par5[1]=strtok(NULL,";");
a->par5[2]=strtok(NULL,";");
break;
}
else
n=1;
}
if(n==1)
printf("The S1 no exist\n");
}
input:
name 15 3 2 tag1 tag2 tag3
output:
name
15
3
2
tag1 tag2 tag3
name
15
3
2
%��j��2 j��2 tag3
For some reason when I try fill the char pointers from file string appears this weir output
why appear this weird chars and whats is wrong in my code?
You are good until you call search_S1_on_file()
Inside this for the array of pointers a->par5 you assign the address of the local variable s.
a->par5[0]=strtok(NULL,";");/* The string being broken into tokens is a local array */
a->par5[1]=strtok(NULL,";");
a->par5[2]=strtok(NULL,";");
Once you exit this function the memory allocated for the array s is freed so accessing this memory location you are bound to get garbage values because this is UB.
In order to fix this keep a char array in main and pass it to the function search_S1_on_file() along with other requierd parameters and that should work.
Alternatively you can try allocating memory on heap for the array s like
char *s = malloc(100); /* Take care to free this memory accordingly */
As a part of a bigger program, I'm trying to combine two arrays of structures. I also was trying to pass the new one into a printing function. I know the function works, because when I pass one of the arrays into it, it prints correctly.
This is the structure, I'm sure it's correct because when I pass an array of it into another function the function works.
typedef struct {
long unsigned bibnum;
char lastname[charnum];
char firstname[charnum];
int grade;
char team[charnum];
char state[charnum];
int time1;
float time2;
} runner_t;
My first two arrays are runarrayboys and runarraygirls, and are arrays of structure type runner_t. The third one is runarrayall. This is how I tried to combine it. When I try to run it I get a segmentation fault. After putting printfs all over the place I'm pretty sure it's in the declaration line of the second for loop.
while (p<(x+y))
{
for (q=0; q<x; q++)
{
runarrayall[q] = runarrayboys[q];
p++;
/* printingfucntion(runarrayall[q]); */
}
for (q=x; q<(x+y); q++)
{
printf("in for loop2 \n");
runarrayall[q] = runarraygirls[n];
n++;
p++;
}
}
When I uncomment the printingfunction, I get this error:
LA2.c:(.text+0xdaa): undefined reference to `printingfucntion'
collect2: ld returned 1 exit status
Even though I passed in the array the same way I did with the others which work
are you initializing runarrayall?
runarrayall = (runner_t *)malloc( sizeof(runner_t)*(x + y) );
So I'm working on a little C program which is a little address book that automatically allocates memory when you add a new contact in it.
I'm using two typedef structures, the first one stores the info on the contact (name telephone etc.):
typedef struct
{
char nom[TAILLE1];
char tel[TAILLE2];
} CONTACT;
The seconde one contains a int with the number of contacts in the address book and an other one is the pointer to the other structure.
typedef struct
{
int nb;
CONTACT * contacts; // tableau
} LISTE_TABLEAU;
I created a function to import contact from a TXT file (first line the name of the person, second line their telephone number and so on). I simplified it with only the basic
int lireDonneesTxt(LISTE_TABLEAU* tab)
{
int i;
tab->contacts = (CONTACT *)malloc(sizeof(CONTACT)*13); (13 because there are 13 contact for testing purposes)
i = 0;
while( !feof(entree) )
{
fgets(ligne, TAILLE1, entree);
strcpy(tab->contacts[i].nom, ligne);
fgets(ligne, TAILLE1, entree);
strcpy(tab->contacts[i].tel, ligne);
i++
}
return 1;
}
When I compile my code there isn't any issue, no warning what so ever.
But when I run my code everything works great until I try and print a name on the screen, then the executable file crashes.
My main function looks something like this:
int main(void)
{
LISTE_TABLEAU *tabb;
tabb->nb = 0;
lireDonneesTxt(&tabb);
printf("%s", tabb->contacts[0].nom);
return 0;
}
If I add the same printf that is in the main at the end of my lireDonneesTxt function it prints the name without any problem.
I'm guessing that the data is not passed correctly to the structure.
I am now blocked and have no idea what to try to make this work !
Don't pass the address of the LISTE_TABLEAU pointer here:
lireDonneesTxt(&tabb);
just pass the pointer
lireDonneesTxt(tabb);
Also setting tabb->nb = 0; to unalocated memory is undefined behaviour.
The memory is not allocated for "tabb" & you are trying to access its member variable (tabb->nb) in main() function. It is illegal, thus the run time crash.
You can try the below code instead:
int main(void)
{
LISTE_TABLEAU tabb;
tabb.nb = 0;
lireDonneesTxt(&tabb);
printf("%s", tabb.contacts[0].nom);
return 0;
}