malloc structure C - c

I can't understand why this litle code doesn't work ! i get it from C struct and malloc problem (C) (selected answer) and I wonder why it doesn't work for me.
any idea ?
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
/* in C code (not C++), don't have to cast malloc's return pointer, it's implicitly converted from void* */
tree* atree = malloc(sizeof(tree)); /* different names for variables */
node* anode = malloc(sizeof(node));
atree->nodes[0] = anode; // <-------- SEG FAULT HERE !
return atree;
}
int main() {
tree* mytree = initTree();
return 0;
}

With a call to
tree* atree = malloc(sizeof(tree));
you have allocated a memory for tree object, so for a struct node** nodes pointer to (as it is a struct member), but it doesn't point to valid memory yet. You have to allocate also a memory for the nodes to which it is supposed to point to. For example:
atree->nodes = malloc( atree->numNodes*(sizeof (node*)));

Related

Why am I getting Segmentation fault (core dumped) or bus error (core dumped) when trying to populate a struct?

So I am trying to use a pointer to a struct of MonsterAttacks as the data that belongs to an element of a linked list. In order to do this I try to populate a struct of MonsterAttacks and then pass that along with a null ptr to a next node to a function called create. However somewhere in the populate method a segmentation fault error occurs. I am working with three files list_demo.c, linked_list.h and linked_list.c. I will build all the the functions that make up a fully functioning linked list, well hoping I can as soon as I get pass this error. Been dealing with this error for about two days and I showed my professor and he could not figure out why its happening, it seems to come from the populate function. I have tried to return a pointer to a strut in which case I get a bus error, and I have tried almost every variation of getting input and storing it on the strut. I even deleted the function and tried to populate it in main, but nothing works. I am new to C and my professor helped me out for about an hour debug this problem and he finally gave up, so any help would be appreciated.
list_demo.c
#include <stdio.h>
#include "linked_list.h"
#include <stdlib.h>
void populate(struct MonsterAttacks *m){
printf("Enter the name for the Monster \n");
scanf("%40s",m->monsterName);
puts("What is his/her attack location?");
scanf("%40s",m->attackLocation);
puts("What are the number of victims this monster has demolished?");
scanf("%ud", &m->numOfVictims);
m->attackID = 0;
}
int main(void)
{
node* tmp = NULL;
struct MonsterAttacks *tmpMonst = (struct MonsterAttacks *)
malloc(sizeof(struct MonsterAttacks));
if(tmpMonst == NULL){
printf("Error allocating memory");
}
else
populate(tmpMonst);
node *head = create(tmpMonst,tmp);
free(tmpMonst);
return 0;
}
linked_list.h
#ifndef LINKED_LIST
#define LINKED_LIST
typedef struct node{
struct MonsterAttacks *monsterAttack;
struct node* next;
} node;
struct MonsterAttacks{
unsigned int attackID;
char monsterName[41];
char attackLocation[41];
unsigned int numOfVictims;
};
/*
create a new node
initialize the data and next field
return the newly created node
*/
node* create(struct MonsterAttacks *m,node* next);
#endif
linked_list.c
// from zentut.com, heavily adapted
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "linked_list.h"
/*
create a new node
initialize the data and next field
return the newly created node
*/
node* create(struct MonsterAttacks *m,node* next)
{
node* new_node = (node*)malloc(sizeof(node));
if(new_node == NULL)
{
printf("Error creating a new node.\n");
exit(0);
}
new_node->monsterAttack->attackID = 0;
new_node->next = next;
strncpy(new_node->monsterAttack->monsterName,m->monsterName,41);
strncpy(new_node->monsterAttack->attackLocation, m->attackLocation, 41);
new_node->monsterAttack->numOfVictims = m->numOfVictims;
return new_node;
}
Btw running on Red Hat using gcc compiler
new_node->monsterAttack->attackID = 0;
Allocating memory for new_node does not allocate memory for the MonsterAttacks struct inside it. That is why dereferencing monsterAttack to get its attackID is causing a seg fault.
A minimal working code
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
// Moved the two structs out to make a minimal reproducible code
/* #include "linked_list.h" */
struct MonsterAttacks{
unsigned int attackID;
char monsterName[41];
char attackLocation[41];
unsigned int numOfVictims;
};
typedef struct node{
struct MonsterAttacks *monsterAttack;
struct node* next;
} node;
void populate(struct MonsterAttacks *m){
printf("Enter the name for the Monster \n");
scanf("%40s",m->monsterName);
puts("What is his/her attack location?");
scanf("%40s",m->attackLocation);
puts("What are the number of victims this monster has demolished?");
scanf("%ud", &m->numOfVictims);
m->attackID = 0;
}
node* create(struct MonsterAttacks *m,node* next)
{
node* new_node = (node*)malloc(sizeof(node));
if(new_node == NULL)
{
printf("Error creating a new node.\n");
exit(0);
}
// Just add this line
new_node->monsterAttack = malloc(sizeof (struct MonsterAttacks));
new_node->monsterAttack->attackID = 0;
new_node->next = next;
strncpy(new_node->monsterAttack->monsterName,m->monsterName,41);
strncpy(new_node->monsterAttack->attackLocation, m->attackLocation, 41);
new_node->monsterAttack->numOfVictims = m->numOfVictims;
return new_node;
}
int main(void)
{
node* tmp = NULL;
struct MonsterAttacks *tmpMonst = (struct MonsterAttacks *)
malloc(sizeof(struct MonsterAttacks));
if(tmpMonst == NULL){
printf("Error allocating memory");
}
else {
populate(tmpMonst);
}
node *head = create(tmpMonst,tmp);
printf("Name: %s\n", tmpMonst->monsterName);
printf("num victim: %d\n", tmpMonst->numOfVictims);
free(tmpMonst);
return 0;
}
When you allocate memory for new_node in create(...), you allocate memory on the heap for a structure of type node to hold all the variables it contains. In this case, monsterAttack in node is initially a pointer to a struct that is pointing to nowhere. You need to explicitly allocate memory for the monsterAttack pointer to point to.
Edit: #bruceg pointed out the lack of semicolon, this malloc isn't the issue. #lightalchemist have highlighted that the second one is the fault.
struct MonsterAttacks *tmpMonst = (struct MonsterAttacks *);
malloc(sizeof(struct MonsterAttacks));
Your malloc call is wrong, malloc allocates and returns a pointer to the memory. You ignore/discard the pointer value.
Later code seems to assume that tmpMonst points to this allocated memory but there is no link between the two.
Try struct MonsterAttacks *tmpMonst = malloc(sizeof(struct MonsterAttacks));

Allocating memory to structure within structure

I'm trying to allocate memory for the code,of which i've only included excerpts from the actual program, that follows below, the problem I am having is that i don't know how to allocate memory to the type Key that lies within BStree_node this leads to the issue of segmentation errors when i try to assign values to variables within Key.
typedef int Data_Item;
typedef char* Sub_Key;
typedef struct {Sub_Key key1; Sub_Key key2;} Key;
struct BStree_node{
Key key;
Data_Item data;
struct BStree_node *left, *right;
}
typedef struct BStree_node BStree_node;
typedef BStree_node** BStree;
BStree bs_tree_ini(void){
BStree tempTreePointer;
tempTreePointer = malloc(sizeof(BStree_node*));
BStree_node *tempNode;
tempNode = malloc(sizeof(BStree_node));
tempNode = NULL;
tempTreePointer = &tempNode;
return tempTreePointer;
}
You could initialize your node like this, using calloc to zero the memory to initialize all the fields properly:
BStree_node *init_node()
{
BStree_node *rval = calloc(1,sizeof(BStree_node)); // so all data & pointers are zeroed
return rval;
}
use it like this: init main, and only left. right stays zeroed: no right node for that main node.
int main()
{
BStree_node *head = init_node();
head->left = init_node();
...
return 0;
}

How to make use of a structure pointer inside the structure itself

I am studying the following C code:
typedef struct msg *m_;
struct msg
{
long from;
long to;
m_ link;
};
m_ queue;
I would like to see an example that explains the role of the pointer, i.e. m_, of the structure inside the structure itself m_ link!
Thank you very much.
To be pedantic: link is a pointer. m_ is not a pointer, it's a typedef. It is used to avoid the need to say "struct msg* link;" inside the struct definition.
As answered in the comment above, the queue is represented by a pointer to the first item, which has a pointer to the second (if any), and so on until you reach a NULL pointer.
It's important to take care when building such lists that no node points to itself or to any precursor, or you get an infinite loop chasing to the tail.
Pointers to the structure type inside the structure itself are very often used for linked lists, trees, etc. In your example, it is referring to a queue implementation.
Here is a very minimal example of a stack implementation using a linked list. The functions require the address of a stack pointer, and an empty stack is a NULL pointer.
struct linked_stack
{
int data;
struct linked_stack *next;
};
void linked_stack_push(linked_stack **stck, int data)
{
struct linked_stack *node = malloc(sizeof(struct linked_stack));
if (node != NULL)
{
node->data = data;
node->next = *stck;
}
*stck = node;
}
int linked_stack_top(linked_stack **stck)
{
if (*stck != NULL)
return (*stck)->data;
return 0; /* stack is empty */
}
void linked_stack_pop(linked_stack **stck)
{
struct linked_stack *node = *stck;
if (*stck != NULL)
{
*stck = node->next;
free(node);
}
}
Example usage:
int main(void)
{
struct linked_stack *stack = NULL;
linked_stack_push(&stack, 10);
printf("top of stack = %d\n", linked_stack_top(&stack));
linked_stack_pop(&stack);
return 0;
}

Passing an uninitialized struct to a function, why is it not null?

I've been scratching my head quite a while at this one. I'm creating my node without any values (and even tried initializing it and a pointer and set it = NULL), but when I get inside the insert function head_ does not evaluate to NULL. I can check for head_->id = NULL but I don't think I should have to do that. Any ideas on what I'm doing wrong? I'm trying to build and traverse a linked list and am certainly not off to a good start! The output is:
head_ =
not null!?
#include <stdio.h>
#include <stdlib.h>
struct node{
int id;
struct node *next;
};
int main(void){
struct node head;
int entered_id;
insert(&head, 1);
}
void insert(struct node* head_, int new_id){
printf("\nhead_ = %s", head_);
if(!head_){
printf("\nnull");
}
else
printf("\nnot null!?");
fflush(stdout);
}
#include <stdio.h>
#include <stdlib.h>
struct node{
int id;
struct node *next;
};
int main(void){
struct node * head = NULL; // create a pointer instead of declaring structure variable
int entered_id;
insert(head, 1);
}
void insert(struct node* head_, int new_id){
// printf("\nhead_ = %s", head_); can you print structure as string?
if(!head_){
printf("\nnull");
}
else
printf("\nnot null!?");
fflush(stdout);
}
If you use struct node head, it will create an object which occupies space and so is not NULL. What you want is a pointer to an object which initially points to nothing and so is null.
The struct is not a pointer to null because it was allocated. If it were declared as:
struct node *head;
then, it would possibly point to NULL, but its not defined.
struct node *head = NULL;
would guarantee its pointing to NULL. Even in that case, you can't allocate it in another function that way. If you in insert did
head = malloc(sizeof(struct node));
then, when main came back, head would still be NULL, and you would have a memory leak.
The way it is defined,
struct node head; //allocates sizeof(struct node) bytes on the stack of main, which is destroyed after main exits.
Make sense?

C struct and malloc problem (C)

It's amazing how even the littlest program can cause so much trouble in C.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
tree* tree = (tree*) malloc(sizeof(tree));
node *node = (node*) malloc(sizeof(node));
tree->nodes[0] = node;
return tree;
}
int main() {
return 0;
}
The compiler says:
main.c: In function 'initTree':
main.c:17: error: expected expression before ')' token
main.c:18: error: expected expression before ')' token
Can you please help?
You're using two variables named tree and node, but you also have structs typedefed as tree and node.
Change your variable names:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
/* in C code (not C++), don't have to cast malloc's return pointer, it's implicitly converted from void* */
tree* atree = malloc(sizeof(tree)); /* different names for variables */
node* anode = malloc(sizeof(node));
atree->nodes[0] = anode;
return atree;
}
int main() {
return 0;
}
tree and node is your case are type names and should not be used as variable names later on.
tree *initTree() {
tree *myTree = (tree*) malloc(sizeof(tree));
node *myNode = (node*) malloc(sizeof(node));
myTree->nodes[0] = myNode;
return myTree;
}
Change (tree*) and (node*) to (struct tree*) and (struct node*). You can't just say tree because that's also a variable.
Change the body of initTree as follows:
tree* myTree = (tree *)malloc(sizeof(tree));
node *myNode = (node *)malloc(sizeof(node));
myTree->nodes[0] = myNode;
return myTree;
Don't use typedef'ed names as variable names, and there is not need to cast malloc(); in C.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
tree->nodes[0] = malloc(sizeof(node));
return malloc(sizeof(tree));
}
int main() {
return 0;
}
I second that Mehrdad's explanation is to the point.
It's not uncommon that in C code you define a variable with the same name as the struct name for instance "node node;". Maybe it is not a good style; it is common in, e.g. linux kernel, code.
The real problem in the original code is that the compiler doesn't know how to interpret "tree" in "(tree*) malloc". According to the compiling error, it is obviously interpreted as a variable.
Apart from the original question, this code, even in it's correct forms will not work, simply due to the fact that tree::nodes (sorry for the C++ notation) as a pointer to a pointer will not point to anything usefull right after a tree as been malloced. So tree->nodes[0] which in the case of ordinary pointers is essentially the same like *(tree->nodes), can't be dereferenced. This is a very strange head for a tree anyway, but you should at least allocate a single node* to initialize that pointer to pointer:
tree *initTree() {
/* in C code (not C++), don't have to cast malloc's return pointer, it's implicitly converted from void* */
tree* atree = malloc(sizeof(struct tree)); /* different names for variables */
/* ... */
/* allocate space for numNodes node*, yet numNodes needs to be set to something beforehand */
atree->nodes = malloc(sizeof(struct node*) * atree->numNodes);
node* anode = malloc(sizeof(struct node));
atree->nodes[0] = anode;
return atree;
}
Interestingly, it does compile cleanly if you simply write the allocations as:
tree *tree = malloc( sizeof *tree );
It is often considered better style to use "sizeof variable"
rather than "sizeof( type )", and in this case the stylistic
convention resolves the syntax error. Personally, I think
this example is a good case demonstrating why typecasts are
generally a bad idea, as the code is much less obfuscated if
written:
struct tree *tree = malloc( sizeof *tree );

Resources