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) );
Related
Let's say I have a file named file1.txt with contents:
one
two
three
Here is my code with a segfault that occurs inside
#include <stdio.h>
#include <pthread.h>
struct example{
char **file;
char **array;
};
void *func(void *arg){
struct example *ex = arg;
char name[1025];
FILE *fp = fopen(ex->file[0], "r");
int k = 0;
while (fscanf(fp, "%1025s", name) > 0){
ex->array[k] = name; // segfault happens here?
k++;
}
return NULL;
}
int main(){
char *sarray[5] = { NULL };
struct example t;
t.file[0] = "file1.txt"
t.array = sarray;
pthread_t tid;
pthread_create(&tid, NULL, func, &t);
pthread_join(tid, NULL);
}
If I do a check:
for (int i = 0; i < 3; i++){
printf("t array: %s and sarray: %s\n", t.array[i], sarray[i]);
}
I want the following output:
t array: one and sarray: one
t array: two and sarray: two
t array: three and sarray: three
Essentially, I want the contents of file to be stored into t.array from the function func and as a result, sarray will have the same values as well. Can anyone help me? I've tried and tested the while loop in func in main and it works, but I want it to work in func.
I would recommend to change few things.
Let's focus first on the main function and the structure example.
You are using struct example t where the fields **file and **array are not allocated.
Luckily, the statement t.file[0]="file1.txt" is okay.
However, if you want to manage n files, the statement t.file[i], with 0 <= i < n, you will get a segfault when 0 < i.
Why ? Because your t.file is not allocated. Therefore the statement t.file[0] is in reality *(t.file + 0) = *(t.file) that can point to the const char[] "file1.txt".
Next, you are doing t.array = sarray;
Keep in mind that using the symbol '=' is not equivalent to an allocation or a copy.
Now, let's have a look on the func function.
Why are you using 'void *' parameter ? Actually you know the type of arg variable.
Same remark as in the main function, you are using the symbol '=' in the statement ex->array[k] = name;
Here, it means that the k-th element points to name.
There is no copy. As a consequence, all elements of ex->array will have the same value as name. Assuming no segfault, you should get 'three three three' and not 'one two three'.
Last but not least, if you have more than 5 lines in your file, you also get a segfault.
Therefore, you should allocate your memory and replace the symbol '=' by strncpy to copy the content of a buffer into antoher memory space.
I've got a project that involves creating a text game. I'm creating a struct for each player and putting them in an array. I'm then trying to pass in data and then pass by pointer the array to other functions, however I keep on getting segmentation faults (Although on the odd occasion working fine). I've summarised below.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char name[9];
int cardsHeld;
int hand[8];
} Player;
void printNames(Player** playerArray)
{
for (int i = 0; i < 3; i++)
{
fprintf(stdout, "%s\n", playerArray[i]->name);
}
}
void gamesetup()
{
int count;
fprintf(stdout, "How many players will be partaking in 'The Game'? ( 1 - 5)\n");
fscanf(stdin, "%d", &count);
Player** playerArray = (Player**)malloc(sizeof(Player*) * count);
for(int i = 0; i < count; i++)
{
playerArray[i] = (Player*) malloc(sizeof(Player));
fprintf(stdout, "Please enter the name for player %d.\n\n", i + 1);
fscanf(stdin, "%s", playerArray[i]->name);
}
printNames(playerArray);
}
int main(int argc, char** argv)
{
gamesetup();
return 0;
}
My questions are;
Is the fscanf getting the address of the Player.name member? I'm getting confused whether the -> operator should deference the value of the struct member or since its in an array the address?
I'm not sure why it works sometimes but not others. If it works sometimes fundamentally it should be ok. Is the malloc function allocating memory it should not or is the fscanf putting data in the wrong place.
Thank you.
-EDIT-
Changed the code so it is in a complete program that appears to work without seg faults. I think that my issues arise from not freeing the memory before termination is messing it up next time I run it without compiling first. I'm still not sure why fscanf works as in my mind the argument playerArray[i]->name is returning the value, not the address.
I've worked it out where I was confused. Thank you for all your help in the comments.
The member I am accessing in my array is a string of chars so the first member is a pointer. By using fscanf(stdin, "%s",playerArray[i]->name); This deferenced the pointer (an address) so it works. I was getting in a muddle as it was an member of an array of structs. The segfaults were caused by me messing with the code to try and fix what already worked.
I do not understand why i have to initialize my structure before using it, i get this error in my code, i know it works if i use pointers or if i initialize the structure members, but why it does not work in this way ?
#include <stdio.h>
typedef struct human{
char name[20];
int age;
} student;
void function(student ){
printf("It's not working");
}
int main(){
student a;
function(a);
return 0;
}
I get this
Debug Error!
File: Run - Time Check Failure #3 - The variable 'a' is being used without being initialized. (Press Retry to debug the application)
and i do not get the message from my function on output
You get this error, because your debugger detect, that you are sending unitialized variable to the function. It doesn't know, what will you do with it inside of the function, so it warns you. You can see, that if you run program in release, no error will occur. Easiest solution for you, if you know, that you will initialize it lately to correct values, is just to initialize it, when creating student a = {0};
You are passing the object a by value to function. As C has only value-semantics, it can only copy values in this case. So, you initialise the parameter (even if your implementation doesn't care about the parameter) with an unitialised object, wich requires reading from that object. This is undefined behaviour, hence the compiler informs you that you are doing something illegal.
If you pass the object via a pointer, you still pass-by-value, but the value being copied is the pointer. Hence you don't have to read the actual value and your compiler wont complain.
Observe:
void flat(student s) {
s.age = 20;
}
void ptr(student* s) {
s->age = 20;
}
int main() {
student s = {"Eve", 0};
// { s.age == 0 }
flat(s);
// { s.age == 0 } --- still the same, no change
ptr(&s);
// { s.age == 20 } --- now it has changed
}
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.
I get the error
subscripted value is neither array nor pointer
when I try to compile my program. I understand it has something to do with the variable not being declared but I checked everything and it seemed to be declared.
static char getValue(LOCATION l)
{
/*return carpark[l.col][l.row]; // Assumes that location is valid. Safe code is
below:
*/
if (isValidLocation(l)) {
return carpark[l.col][l.row]; <<<<<<<< this line
} // returns char if valid (safe)
else {
return '.';
}
Which corresponds to this part of the code in the header
typedef struct
{
/* Rectangular grid of characters representing the position of
all cars in the game. Each car appears precisely once in
the carpark */
char grid[MAXCARPARKSIZE][MAXCARPARKSIZE];
/* The number of rows used in carpark */
int nRows;
/* The number of columns used in carpark */
int nCols;
/* The location of the exit */
LOCATION exit;
} CARPARK;
Carpark was declared in the main prog with:
CARPARK carpark.
Thanks for the help.
carpark is not an array so you probably want something like:
return carpark.grid[l.col][l.row];
The error message is telling you exactly what the problem is. The variable carpark is neither an array nor a pointer, so you cannot apply the [] operator to it.
carpark.grid, however, is an array, so you could write
return carpark.grid[l.col][l.row];