Struct Pointers Segmentation Fault, How can I solve this? - c

I have these structures in C:
typedef struct Game{
char* name;
char* team_1;
char* team_2;
int score[2];
} *pGame;
typedef struct Team{
char *name;
int victories;
} *pTeam;
typedef struct node_game{
pGame game;
struct node_game *next;
} *link_game;
typedef struct node_team{
pTeam team;
struct link_team *next;
} *link_team;
typedef struct head{
link_game game_list;
link_team team_list;
} *pHead;
And these functions to go with it:
void initialize(pHead* heads,int m){
int i;
heads = (pHead*)malloc(m*sizeof(pHead));
for (i = 0; i < m; i++)
heads[i] = NULL;
}
//this function is to allocate dynamic memory for a string
char* str_dup(char* buffer){
char* str;
str = (char*) malloc(sizeof(char)*(strlen(buffer)+1));
strcpy(str,buffer);
return str;
}
void add_team(pHead* heads, char* name){
char* name_dup;
link_team new_team = (link_team) malloc(sizeof(struct node_team));
name_dup = str_dup(name);
new_team->team->name = name_dup; //this line gives me segmentation fault
}
int main(){
pHead* heads;
initialize(heads,M);
add_team(heads, "manchester");
return 0;
}
Why is it that the last line of add_team gives me segmentation fault? I've looked at this with the VSC debugger and it seems it should go well. My problem is most likely that I'm not allocating memory when I should, but I can't see where. (also, the function will do more stuff, but it gives me segmentation fault already there).

At the time you do this:
new_team->team->name = name_dup;
You allocated memory for new_team, but not for new_team->team. This means that new_team->team->name dereferences an uninitialized pointer invoking undefined behavior.
You need to allocate space for it first:
link_team new_team = malloc(sizeof(struct node_team));
new_team->team = malloc(sizeof(struct Team));
Or you can change team from a struct Team * to a struct Team and access it directly. You probably want to do the same for game in struct node_game.

Related

Segmentation fault using multiple structs

I'm kinda new in C. I'm having some trouble using pointers and stuff like that.
I made this piece of code to try to understand why does it return me Segmentation Fault.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct lligada {
int userID;
struct lligada *prox;
} *LInt;
typedef struct {
int repo_id;
LInt users;
} Repo;
typedef struct nodo_repo {
Repo repo;
struct nodo_repo *left;
struct nodo_repo *right;
} *ABin_Repos;
void createList (int id_user, int id_repo) {
ABin_Repos temp = malloc(sizeof(struct nodo_repo));
temp->repo.repo_id = id_repo;
temp->repo.users->userID = id_user;
temp->left = NULL;
temp->right = NULL;
printf("%d", temp->repo.users->userID);
}
int main() {
int id_user, id_repo;
scanf("%d %d", &id_user, &id_repo);
createList(id_user, id_repo);
return 0;
}
I really don't understand.
Sorry if this is a stupid question.
Thank you!
The type of users is LInt and LInt is an alias of type struct lligada *:
typedef struct lligada {
int userID;
struct lligada *prox;
} *LInt;
That means the type of users is struct lligada *.
In the createList(), you are accessing users pointer before allocating it. Hence, you are getting segmentation fault.
You should do:
void createList (int id_user, int id_repo) {
ABin_Repos temp = malloc(sizeof(struct nodo_repo));
// Allocate memory to users
temp->repo.users = malloc (sizeof (struct lligada));
// check malloc return
if (temp->repo.users == NULL) {
// handle memory allocation failure
exit (EXIT_FAILURE);
}
temp->repo.repo_id = id_repo;
temp->repo.users->userID = id_user;
.....
.....
Additional:
Follow good programming practice, make sure to check returned value of function like scanf() and malloc().

C malloc segmentation fault struct

In the textbook my teacher provided us, there is this C code's sample, which when I try to run gives a Segmentation Fault error:
const celula *nulo = NULL;
typedef char informacao;
typedef celula *noh;
typedef celula *arvore;
struct celula {informacao info; noh pai; noh fesq; noh idir;};
...
typedef struct celfloresta celfloresta;
typedef struct celfloresta *floresta;
typedef struct celfloresta *posicfloresta;
struct celfloresta {arvore elem; celfloresta *prox;};
...
void FormarListaNohs(){
floresta p = (floresta)malloc(sizeof(celfloresta));
p->elem->info = '3';
}
...
Why does the line
p->elem->info = '3';
give segmentation fault here?
elem is a pointer. You need to allocate memory for it:
p->elem = malloc(sizeof(arvore));
Basically malloc return a void pointer then to cast is should use a variable of type pointer
an example :
int *p = malloc(sizeof(int))
struct s_list *l = malloc(sizeof(struct s_list))
then you can dereference the pointer for example
l->data = 12;

Assign struct to char array

I am trying to create my own malloc but I am stuck on one point. As we know we have to assign struct as a meta data in available space as it is mentioned in this picture.
char heap_space[MEM_BUFFER];
struct myblock
{
struct myblock *next;
struct myblock *prev;
int size;
char *buffer;
}
I have my heap_space which will be my "RAM" . Now I am stuck on one point:-
How to assign my structure myblock to heap_space, and one thing which we should keep in mind that every time when new request will come, the place of the myblock will be changed as per allocated (requested) space.
I'm not sure to understand your problem but why don't you try something like:
#define MEM_BUFFER 4096
#define size_t unsigned int
char heap_space[MEM_BUFFER] = {0};
struct myblock
{
struct myblock *next;
struct myblock *prev;
int size;
char *buffer;
};
void *malloc(size_t size)
{
struct myblock *tmp = heap_space;
if (tmp != 0) // != 0 since NULL is in stdlib
while (tmp->next != 0)
tmp = tmp->next;
struct myblock *new_elem = tmp; //your question I guess
new_elem->prev = tmp;
new_elem->size = size;
new_elem->buffer = new_elem + sizeof(*new_elem);
new_elem->next = new_elem->buffer + new_elem->size;
return (new_elem->buffer);
}
int main()
{
char *str1 = malloc(10);
char *str2 = malloc(10);
strcpy(str1, "Hello");
strcpy(str2, "World");
printf("%s %s\n", str1, str2);
}
You should just think your memory in a different way I guess, where inside your heap_space you can have many things.
If you don't understand something please ask.
You should also use void * and unsigned int instead of int
Furthermore you still have some stuff to do:
Check if the size required is available in your array
Give a little more space in case you want to implement your
realloc
Implement your free function
And if you are on linux, you should try to use brk/sbrk instead of having your 'heap space'. But the greatest thing is to run 'real' programs with your own malloc (using LD_PRELOAD)
If it's C++, you should use myblock *free_ptr = reinterpret_cast<myblock*>(heap_space); to initialize your free pointer, and then initialize the size, next, prev and buffer of free_ptr.
In C, you would use a regular C style cast, struct myblock *free_ptr = (struct myblock*)heap_space;.
You should declare
struct myblock
{
struct myblock *next;
struct myblock *prev;
int size;
char buffer[0];
}
so your malloc will return myblockvar.buffer.

store an int in a node

#include <stdio.h>
#include <stdlib.h>
struct Fraction {
int num;
int denom;
};
struct PolyTerm {
int expo;
struct Fraction coeff;
};
struct PolyNode {
struct PolyTerm* dataPtr;
struct PolyNode* next;
};
typedef struct Fraction* FractionAddr;
typedef struct PolyNode* PolyNodeAdr;
typedef struct PolyNode* PolyList;
int main() {
int exponet;
PolyNodeAdr polyNode = 0;
printf("\n\tPlease Enter expoent: ");
scanf("%d", &exponet);
polyNode->dataPtr->expo = exponet;
//printf("\n%d\n",polyNode->dataPtr->expo);
return;
}
on the above code, I am trying to store the exponet into the expo in the struct of polynode
but I tried many ways, but errors keep appearing
isn't expo is an int? why I can't store the exponet (int) into it?
I checked a few ways, when I just put struct PolyTerm dataPtr;in the struct of polyNode
and polyNode->dataPtr.expo = exponet; in the main, it would work
I think because the dataPtr is a pointerstruct PolyTerm* dataPtr;
but I have no idea to fix it
can anyone explain to me why I can't do that and what is the solution for it?
You have to allocate memory for all pointers that you gonna dereference. And free the memory after you are done with it.
int main() {
int exponet;
PolyNodeAdr polyNode = (PolyNodeAdr)malloc(sizeof(PolyNode));
polyNode->dataPtr = (PolyTerm*)malloc(sizeof(PolyTerm));
printf("\n\tPlease Enter expoent: ");
scanf("%d", &exponet);
polyNode->dataPtr->expo = exponet;
//printf("\n%d\n",polyNode->dataPtr->expo);
free(polyNode->dataPtr);
free(polyNode);
return 0;
}
No memory was allocated for PolyNodeAdr polyNode
You have to add this after your declaration of polyNode for polyNode->dataPtr->expo = exponet; to work
polyNode = malloc( sizeof( struct PolyNode )) ;
polyNode->dataPtr = malloc( sizeof( struct PolyTerm )) ;
Note the usage of struct PolyNode not PolyNodeAdr since you changed PolyNodeAdr to a pointer with typedef.
Also you shouldn't typedef a pointer, since you lose the information that the name is a pointer.
For example:
typedef struct PolyNode* PolyNodeAdr;
Should be:
typedef struct PolyNode PolyNodeAdr;
So later you declare:
PolyNodeAdr * polyNode;
You are Dereferencing a NULL pointer.
polyNode == NULL
dataPtr == anything.
so polyNode->dataPtr->expo is actually (NULL)->dataPtr->expo. it doesnt have meaning. there is segmentation fault because you are trying to access a restricted memory. thats why windows pops that message.
EDIT:thanks to #Nik for pointing out the errors in my answer.

A simple stack implementation using C

I had written a program in C to implement a simple stack. But I am getting segmentation fault in my program and finding it hard to find out what is wrong. Can any one help,
#include<stdio.h>
#include<stdlib.h>
struct stack_structure{
int stack_array[10];
int stack_pointer;
};
void push_into_stack(struct stack_structure *,int);
int main(){
int no = 8;
struct stack_structure *st;
st->stack_pointer = -1;
push_into_stack(st,no);
return 0;
}
void push_into_stack(struct stack_structure *s,int no){
s -> stack_pointer++;
s -> stack_array[s -> stack_pointer] = no;
}
struct stack_structure *st;
This only creates a pointer to a struct stack_structure. It does not allocate memory for the struct stack_structure itself.
You can try with this:
struct stack_structure st;
st.stack_pointer = -1;
push_into_stack(&st,no);
The other option is to dynamically allocate (and free) that structure:
struct stack_structure *st = malloc(sizeof(struct stack_structure));
...
// when you're done with it
free(st);
See these lines:
struct stack_structure *st;
st->stack_pointer = -1;
You've declared a pointer variable but then you're using it uninitialized. A pointer has to point at something, and this one doesn't have anything to point to. The simplest fix would be to change these lines to:
struct stack_structure st1, *st=&st1;
st->stack_pointer = -1;
You need to malloc some space for the structure:
struct stack_structure *st = malloc(sizeof(struct stack_structure));

Resources