I have the following data structure:
typedef struct node
{
int key;
int *v;
}node;
... and the global variables:
node *multiway[10];
int contor=0;
I am trying to insert inside this structure all the nodes of a multiway tree, and all the kids of each node. In order to do this, I made this function:
int * getKids(int value,int n) //returneaza vectorul de copii ai unui nod
{
//value-nodul parinte
//n- numarul de noduri ale vectorului
int *result=(int*)malloc(n*sizeof(int));
int counter=0;
int i;
for(i=1;i<=n;i++)
{
if(a[i]==value)
{
counter++;
result[counter]=i;
printf("%d ",result[counter]);
}
}
int copii[counter]; //in vector pun toti copiii valorii date, value
for(i=1;i<=counter;i++)
{
copii[i]=result[i];
}
contor++;
multiway[contor]=(node*)malloc(sizeof(node)); //added this line after a comment
multiway[contor]->key=value; //SEGMENTATION FAULT
multiway[contor]->v=copii;
return result;
}
My code compiles with no warnings, but when I run, it crashes. When I debug, I get a segmentation fault at the line which I commented with "Segmentation fault". Any idea of what I did wrong? Thank you.
Many issue with your code. To point out some of them
Array indexing
for(i=1;i<=n;i++)
{
if(a[i]==value)
arrays in c has 0 based index. So, basically it should be for(i=0;i< n;i++). You also did not show us what a is.
In case of
int copii[counter];
what if if(a[i]==value) never becomes TRUE?
In case of
multiway[contor]->key=value; //SEGMENTATION FAULT
multiway[contor]->v=copii;
what if contor is more than 9? You'll be overrunning the memory.
a function local variable's lifetime is till the function finishes execution. Once the function is finished, that variable won't be present anymore. Trying to access that variable produces undefined behavior.
multiway[contor]->v=copii;
in the above case, copii is local to getKids(), and after getKids() finishes execution, trying to access multiway[contor]->v will lead to UB.
Note: Do not cast the return value of malloc() and family.
Related
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 need to simulate a hard disk for a college assignment. I have a char array inside a struct, another struct has an array of the last struct and so on. The teacher asked for it to be done this way.
typedef struct block {
unsigned char bytes_s[512];
} block;
typedef struct sectror_array {
block sector[60];
} sectror_array;
typedef struct track_array {
sectror_array track[5];
} track_array;
All of that in a
track_array cylinder[10];
declared as global.
my problem is that i can't seem to access any of these. In my code, i use a loop to assign a variable to the "byte" and then try to print it
int c=0, t=0, s=0, b=0;
while(c<11){
if(b==512){
b=0;
s++;
if(s==60){
s=0;
t++;
if(t==5){
t=0;
c++;
if(c==10){
return;
}
}
}
}
cylinder[c].track[t].sector[s].bytes_s[b]=0;
b++;
printf("%d %d %d %d, %c\n",c, t, s ,b,
cylinder[c].track[t].sector[s].bytes_s[b]);
But it shows nothing even as i tryed to assign 'a' to every byte.
Yet it compiles and runs without crashes.
Never had to work with such before and i'm out of ideas of how to fix this.
https://github.com/diceEviscerator/trabOA
code is my_drive.cpp
saved as cpp but is pure c (needed to save as cpp to run gtest)
while (cylinder[j].track[t].sector[s * 4].bytes_s[0] != 0) {
The program just won't simply enter the loop.
I tried to "initialize" the struct by making a loop that would assign 0 to every byte
So, an extremely simplified version of what you describe looks like this?
int main (void)
{
int x = 0; // Initialize to 0
while ( x != 0 ) // While not 0, do some work
{
x = 1;
}
}
Break your problem down into small parts and code it in small increments, verifying each as you go. "Big Bang" coding adds too much complexity at once and makes problems much harder to find.
So far the problem is that i was tring to print the character after the one i changed
cylinder[c].track[t].sector[s].bytes_s[b]=0;
b++;
printf("%d %d %d %d, %c\n",c, t, s ,b, cylinder[c].track[t].sector[s].bytes_s[b]);
where should be:
cylinder[c].track[t].sector[s].bytes_s[b]=0;
printf("%d %d %d %d, %c\n",c, t, s ,b, cylinder[c].track[t].sector[s].bytes_s[b]);
b++;
there are still problems with this code but this problem seems solved. It wasn't clear to me at the time I posted and I wish i could delete since it is so simple thus is no new knowledge , but i can't.
I have a function that looks through a number of matches from an array and find all teams in matches, that meet some conditions. When found they need to be assigned to a new array. The new array should be used as an output parameter.
I get segmentation fault: 11 when I call it. I have tried to debug but cannot seem to get why. Following is declared in main:
TEAM team_least_viewers;
double spectators = 99999;
solve_task_four(round, team, &team_least_viewers, &spectators);
And the function itself:
void solve_task_four(ROUND *round, TEAM *team, TEAM *team_least_viewers, double *spectators) {
int i, j, k = 0;
for(i=0; i<ROUNDS_PR_SEASON; i++) {
for(j=0; j<MATCH_PR_ROUND; j++) {
if(round[i].match[j].year == 2015) {
/* Searching for team name in team[]*/
for(k=0; k<NUMBER_OF_TEAMS; k++) {
/* If it matches */
if (round[i].match[j].home_team == team[k].name) {
team[k].spectators_home_last_year += round[i].match[j].spectators;
}
}
}
}
for(k=0; k<NUMBER_OF_TEAMS; k++) {
if(team[k].spectators_home_last_year < *spectators) {
*spectators = team[k].spectators_home_last_year;
}
}
}
}
The structs as requested:
typedef struct {
char weekday[WEEKDAY_SIZE], start_time[START_TIME_SIZE],
home_team[TEAM_SIZE], away_team[TEAM_SIZE];
double spectators;
int day, month, year, round, home_team_score, away_team_score;
} MATCH;
typedef struct {
MATCH match[MATCH_PR_ROUND];
} ROUND;
typedef struct {
char *name;
int points, matches_played,
matches_won, matches_draw, matches_lost,
matches_won_home, matches_won_away,
goals_for, goals_against, goal_difference;
double spectators_home_last_year;
} TEAM;
Any help is much appreciated.
I infer your questions is: How do I figure out what is causing the segmentation fault? If that's right, then one answer is to use a debugger. Another answer would be to add print statements throughout the code. The segfault is almost certainly one of the array indexings, like round[i] or round[i].match[j], so be sure to print the i and j values. You may be indexing past the end of an array or dereferencing a null pointer or an uninitialized pointer, so print the pointer values, like printf("round[%d] at %p\n", i, &round[i]).
SIGSEGV on several operating systems is signal 11, and is delivered to the process on a segmentation fault.
Segmentation faults occur when your program accesses memory in a way which isn't allowed, usually by attempting to dereference a null pointer or running off the end of an array.
In your program, the most likely culprits are are array indexes, round[i].match[j] and team[k]. (Another possibility would be if the spectator argument passed were not a valid location for writing, but this is unlikely in this particular case.) You may wish to insert code/run in a debugger to check whether each access is correct.
In particular, assuming that your ROUNDS_PR_SEASON &c. values are correct, it seems most likely that some round[i].match contains a null, if your round array was not fully initialized.
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.