Error while initializing the structure values - c

I have just started using pointers.So please bear with me if this looks silly
But I am not able to find the reason.
I have a structure
typedef struct Intermediatenode
{
int key;
char *value;
int height;
struct node *next[SKIPLIST_MAX_HEIGHT];
} node;
And I wand to create a new node by using below function
node *create_node(int key, char * val, int h)
{
node *newnode;
newnode=malloc(sizeof(node));
newnode->height=h;
newnode->key=key;
printf("till here %s \n",val);
printf("till here %d \n",newnode->height);
printf("till here %d \n",newnode->key);
strcpy(newnode->value,val);
printf("till here %s \n",newnode->value);
return newnode;
}
But I Am getting segmentation fault at this
"strcpy(newnode->value,val);"
Can you please help me with that.Thanks a lot

You allocated memory for the node, but not the string in value. The strcpy function will copy bytes but not allocate memory. It assumes that you've already arranged that. In a pinch, you can allocate and copy the string with strdup:
newnode->value = strdup(val);

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));

Segmentation Fault with string compare

When working with a basic example like this, I am getting a segmentation fault. I believe it's due to the size of the data not being fixed. How can I have variable length data attached to a struct?
struct Node {
char * data;
struct Node* next;
};
void compareWord(struct Node** head_ref, char * new_data) {
if (strcmp((*head_ref)->data, new_data) > 0) {
head_ref->data = new_data;
}
}
int main(int argc, char* argv[]) {
struct Node* head = NULL;
head->data = "abc";
char buf[] = "hello";
compareWord(&head, buf);
return 0;
}
How can I have variable length data attached to a struct?
Answer is - No, you cannot. The reason is the size of the struct should be known at compile time.
The reason for segmentation fault is, your program is accessing head pointer before allocating memory to it:
struct Node* head = NULL;
head->data = "abc";
Allocate memory before using head:
struct Node* head = NULL;
head = malloc (sizeof(struct Node));
if (NULL == head)
exit(EXIT_FAILURE);
head->data = "abc";
Make sure to free allocated memory once you have done with it.
There is something known as Flexible Array Member(FAM) introduced in C99 standard. It may be of your interest.

Storing object in BinarySearchTree leads to weird dereference problems

For an assignment I need to write code that takes a string as input and counts what word is the most used in that string.
We need to implement this using a Binary Search Tree of a structure called "WordCount" that contains a character array and the count of how many times the word appears.
This is how the structure is defined.
struct wordcount {
char word[80];
int count;
};
typedef struct wordcount WordCount;
A binary search tree must have a way to create nodes, this is the code:
BSTnode* createNode(void* item) {
BSTnode* newNode = (BSTnode*) malloc(sizeof(BSTnode));
newNode->item = item;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
When I store the WordCount structure inside of the Binary Search Tree and attempt to access the item, and then access the word, I get a Segmentation Fault.
If I just try to access the item of the tree, I get the char word array. This doesn't make sense because I'm storing the wordCount structure, so I should have to dereference it twice.
int main(int argc, char* argv[]) {
if (argc >= 1) {
WordCount* firstWord = (WordCount*) malloc(sizeof(WordCount));
strcpy(firstWord->word,argv[1]);
firstWord->count = 0;
BSTnode* BST = createNode(firstWord);
printf("%s", BST->item); // should be BST->item->word...but this does not work and says that it cannot find "word" which is apart of
}
/*int i;
char string[80];
for(i = 1; i < argc; i++) {
sscanf(argv[i], "%s", string);
//printf("%s ", string);
//insert(main, argv[i], wordCountCompare);
}*/
}
Any help is greatly appreciated. Let me know if my explanation was entirely vague or incomplete or if I'm overlooking something entirely.
I also want to clarify that the printf statements are merely for debugging only they won't be apart of the actual program...however the point still stands.
Definition of BSTnode:
struct bstnode {
void *item;
struct bstnode *left;
struct bstnode *right;
};
typedef struct bstnode BSTnode;
Your item should be of wordcount type.
struct bstnode {
wordcount *item;
struct bstnode *left;
struct bstnode *right;
};
typedef struct bstnode BSTnode;
You can't be dereferencing void pointers (which lead to the compilation error)
You're likely getting these errors because you're trying to dereference a pointer to NULL. Learn how to use the debugger!. Hint: break in main and step thru the function to see where the segmentation fault occurs
printf("%s", BST->item);
Printf's "%s" expects a string, and item is a structure. Try:
printf("%s" BST->item->word);

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?

Segmentation fault (core dumped) while running the program

#include<stdio.h>
#include<string.h>
#include<malloc.h>
//#include<conio.h>
struct list
{
char *value;
struct list *link;
};
struct list *arr[12];int val;
int hf(char *item)
{
int sum,i=0;
while(item[i]!='\0')
{
sum+=item[i];
i++;
}
return sum%12;
}
void insert(struct list ** arr,char *item,int val)
{
struct list *temp,*r;
r=*arr;
temp=(struct list *)malloc(sizeof(struct list));
strcpy((temp->value),item);
if(strcmp((r->value),NULL))
{
strcpy((r->value),(temp->value));
(r->link)=NULL;
}
else
{
while(r->link!=NULL)
r=r->link;
r->link=temp;
r=r->link;
strcpy((r->value),(temp->value));
r->link=NULL;
}
*arr=r;
}
void main()
{
struct list *li[12];int i=0;
for(i=0;i<12;i++)
{
li[i]=NULL;
}
char *item;int ret;
strcpy(item,"Steve");
ret=hf(item);
insert(&li[ret],item,ret);
strcpy(item,"raj");
ret=hf(item);
insert(&li[ret],item,ret);
strcpy(item,"Notes");
ret=hf(item);
insert(&li[ret],item,ret);
}
The above program is to implement array of linked list and im trying to insert string
as the value. When i am trying to run the program, there are no errors but it tells segmentation fault(core dumped)
so please explain the reason
The code
char *item;int ret;
strcpy(item,"Steve");
tries to copy the string literal "Steve" to an uninitialised pointer. You need to allocate memory for item. The easiest way of doing this is to hard-code a suitably sized stack buffer
char item[50];
You also have a similar problem inside insert. You could solve this in the same way
struct list
{
char value[50];
struct list *link;
};
or you could dynamically allocate the correct size of buffer inside insert
temp->value = malloc(strlen(item) + 1);
if (temp->value == NULL) {
/* handle oom error */
}
strcpy(temp->value, item);
In this latter approach, make sure to free(node->value) when you free that list node. Note also that freeing of all dynamically allocated memory is currently missing from your program, meaning that you leak all memory allocated using malloc.
There is one more bug in your code - insert assumes that arr is a pointer to a valid list* but it is always NULL. You need to update either main or the assumption in insert here.
change the following
In insert() function change the if loop
if(r==NULL){
r = temp;
}
Change the structure. change the size of the structure for your need
struct list
{
char value[25];
struct list *link;
};
Change the variable item to
char item[25];
EDIT :
There is no need to typecast the output of malloc

Resources