C malloc segmentation fault struct - c

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;

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().

Struct Pointers Segmentation Fault, How can I solve this?

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.

Free a pointer to struct cause the program to get "stuck"

given the following C code:
struct list_element
{
struct list_element * next;
};
typedef struct list_element list_element;
typedef struct
{
list_element header;
int value;
} *apple;
apple a = malloc(sizeof(apple));
a->value = 1;
free(a);
However, the program get "stuck" in the free() function (in release configuration, the program crash). I also tried free(&a) to free the dress that holds the pointer, but nothing seems to be works.
What am I doing wrong?
apple a = malloc(sizeof(apple));
Will allocate memory with size of pointer not actual structure.
Avoid typdefing structure to pointer;
typedef struct
{
list_element header;
int value;
} apple;
apple *a = malloc(sizeof(apple ));
or
Best approach would be referring the type which pointer is holding like below.
typedef struct
{
list_element header;
int value;
} *apple;
apple a = malloc(sizeof(*a));

Is it possible to generically free linked lists' memory in C

If I have several linked structures in C like:
struct structA {
int a;
int b;
struct structA *next;
}
struct structB {
char a;
int b;
struct structB *next;
}
and I dynamically allocate memory like this:
struct structA *mystructA = (struct structA*) malloc(sizeof(struct structA));
mystructA->next = (struct structA*) malloc(sizeof(struct structA));
struct structB *mystructB = (struct structB*) malloc(sizeof(struct structB));
mystructB->next = (struct structB*) malloc(sizeof(struct structB));
do I always have to free it for each struct type like this:
struct structA *p, *pNext;
for (p = mystructA; p != NULL; p = pNext) {
pNext = p->next;
free(p);
}
struct structB *p, *pNext;
for (p = mystructB; p != NULL; p = pNext) {
pNext = p->next;
free(p);
}
or is there any generic solution? I assume there is no other solution because the free() procedure must know how many bytes have to be freed. But maybe I'm wrong and someone can teach me better.
The standard way is to make the "list part" the first element of the structure, and let each derived struct share this same prefix. Since the first element is guaranteed to be placed at offset zero this wil work.
Example snippet:
#include <stdlib.h>
#include <string.h>
struct list {
struct list *next;
};
struct structA {
struct list list;
int a;
int b;
};
struct structB {
struct list list;
char a;
int b;
};
void *create_any(size_t size)
{
struct list *this;
this = malloc (size);
if (!this) return this;
memset(this, 0, size);
this->next = NULL;
return this;
}
void free_all_any(struct list **lp) {
struct list *tmp;
while ((tmp = *lp)) { *lp = tmp->next; free(tmp); }
}
#define CREATE_A() create_any(sizeof(struct structA))
#define CREATE_B() create_any(sizeof(struct structB))
#define FREE_A(pp) free_any((struct list **) pp)
#define FREE_B(pp) free_any((struct list **) pp)
int main(void)
{
struct structA *ap;
struct structB *bp;
ap = CREATE_A ();
bp = CREATE_B ();
// some code here ...
FREE_A( &ap);
FREE_B( &bp);
return 0;
}
This is more or less the method used in the linux kernel, but a lot more preprocessor magic is used there. (and there is no malloc there, obviously)
Since free() accepts pointers to void * and structA and structB both have the same size, you can pass both pointer types.
This is, however, not optimal in terms of elegance. You should think about the following questions:
Why do you have two different structs with the same members?
Why do you not have a generic list item type, such as the following:
struct list_node {
void *data;
struct list_node *next;
}
Actually, this is a very interesting question. The part is true that you have to free() each struct type individually, as they have been malloc()-ed individually, and each memory block has been allocated specifically for that type.Also, on some systems char and int have different storage sizes, but you can try a solution like Phillip provided. For more info, read about the doom memory engine. On a side note, please don't cast malloc() in C. The funny thing is that once the program is terminated, the operating system will reclaim the memory, so if you only deallocate the structures near the end of the program, when you don't need them anymore, it may not be necessary to free() them

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