ds_list can't handle more than 3 elements - c

i don't know why i can't even add 4th element...
(im working on windows with mingw)
this is my code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 100
typedef struct ds_list_element {
char value[MAX];
struct ds_list_element *next;
}* ds_list;
int ds_list_empty(ds_list id) { // id listy
if (id == NULL) return 1;
else return 0;
}
ds_list ds_list_add(ds_list id, char add[MAX]) {
ds_list temp;
temp = (ds_list)(malloc(sizeof(ds_list)));
strcpy(temp->value,add);
temp->next = id;
return temp;
}
void ds_list_print(ds_list id) {
if (ds_list_empty(id) == 0) {
printf("%s\n",id->value);
ds_list_print(id->next);
}
}
int main () {
ds_list my_list = NULL;
my_list = ds_list_add(my_list,"one");
my_list = ds_list_add(my_list,"two");
my_list = ds_list_add(my_list,"three");
my_list = ds_list_add(my_list,"four");
ds_list_print(my_list);
return 0;
}
and the result is:
four
three
two
y
Press any key to continue . . .
i don't know why it is happening. everything should work fine.
my friend told me it is working on ubuntu...

temp = (ds_list)(malloc(sizeof(ds_list)));
will be
temp = malloc(sizeof(*temp)));
You want to allocate memory for struct ds_list_element not struct ds_list_element*. Don't hide pointers behind typedef name. It rarely helps.
Also you should check the return value of malloc and the casting is not needed.

Use ds_list as structure not a pointer
typedef struct ds_list_element {
char value[MAX];
struct ds_list_element *next;
}ds_list;
and allocate memory for the structure not a pointer.
Working program:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 100
typedef struct ds_list_element {
char value[MAX];
struct ds_list_element *next;
}ds_list;
int ds_list_empty(ds_list *id) { // id listy
if (id == NULL) return 1;
else return 0;
}
ds_list * ds_list_add(ds_list *id, char add[MAX]) {
ds_list *temp;
temp = (malloc(sizeof(ds_list)));
strcpy(temp->value,add);
temp->next = id;
return temp;
}
void ds_list_print(ds_list *id) {
if (ds_list_empty(id) == 0) {
printf("%s\n",id->value);
ds_list_print(id->next);
}
}
int main () {
ds_list *my_list = NULL;
my_list = ds_list_add(my_list,"one");
my_list = ds_list_add(my_list,"two");
my_list = ds_list_add(my_list,"three");
my_list = ds_list_add(my_list,"four");
ds_list_print(my_list);
return 0;
}
Output:
four
three
two
one

Related

Is there any way to 'reserve' some memory for a struct to make sure other functions can't overwrite it?

For context, I'm a new programmer to C and I wanted to make a toy implementation of a dictionary/map from a 'Person' struct to an integer. I'm using separate chaining, so I have a hash table of linked list pointers.
So far, I've been able to add one value to the linked list just fine, but when I call the function to get the value for the Person key I'm using, the memory at one of my nodes seems to get overwritten.
More info if it's helpful, using a singly linked list with one sentinel node at the head and a tail reference.
New to StackOverflow, so I can't actually embed the image, but pictured on left is the HashTable at the beginning of the function call, when nothing has been changed. The relevant stuff is the expanded part of the Variables menu, which shows that at position 58 is a pointer to 0x61f8e0, the linked list. The linked list has a head pointer to 0x61f760, which is the sentinel value, and a tail pointer to 0x61f864, currently pointing to a Node with the value (3) for a Person named Robert who's 36 years old. The tail pointer's next field points to 0x0 (not pictured), like intended. The picture follows: https://i.stack.imgur.com/F9EJ9.png
This is what happens as soon as the first statement (which hashes the Person pointer very naively) is executed: https://i.stack.imgur.com/UJvGy.png. As you'll see, the value is now some random long number, the intrinsic age is now 1 instead of 36, the saved name is now gibberish, and worst of all the next pointer now points somewhere completely random (0x61fb10).
The function in question follows.
int tableGet(HashTable t, Person key) {
int position = hash(&key) % 100;
List* listLoc = t.table[position];
if ((int) listLoc == 0) {
return -1;
}
Node curr = *(listLoc -> head);
while (curr.next != NULL) {
if (curr.savedAge == key.age && curr.savedName == key.name) {
return curr.val;
}
curr = *curr.next;
}
return -1;
}
Here is the hash function, in case that's what's causing the problems.
int hash(Person* p) {
int sum;
Person person = *p;
int i = 0;
char nameChar = person.name[i];
while (nameChar != '\0'){
sum += (int) nameChar;
i += 1;
nameChar = person.name[i];
}
return (int) (person.age + sum);
}
And just because why not, here's all of the short amount of code I've written for this.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
typedef struct Node {
int val;
int savedAge;
char savedName[100];
struct Node* next;
} Node;
typedef struct {
int age;
char name[100];
} Person;
typedef struct {
Node* head;
Node* tail;
} List;
typedef struct {
List* table[100];
} HashTable;
int hash(Person*);
Person person(int age, char name[]) {
Person p;
p.age = age;
strcpy(p.name, name);
return p;
}
Node node(int val, Person p, Node* next) {
Node n;
n.val = val;
strcpy(n.savedName, p.name);
n.savedAge = p.age;
n.next = next;
return n;
}
List list() {
List l;
Node head = node(-1, person(0, "SENTINEL"), NULL);
l.head = &head;
l.tail = l.head;
return l;
}
void listAdd(List* l, Node n) {
Node* newTailPtr = &n;
l -> tail -> next = newTailPtr;
l -> tail = newTailPtr;
}
HashTable table() {
int table[100] = {0};
HashTable t;
memcpy(t.table, table, sizeof table);
return t;
}
HashTable tableAdd(HashTable t, Person key, int val) {
int num = hash(&key) % 100;
List* loc = t.table[num];
if ((int) loc == 0) {
List newList = list();
t.table[num] = &newList;
}
listAdd((List*) t.table[num], node(val, key, NULL));
return t;
}
int tableGet(HashTable t, Person key) {
int position = hash(&key) % 100;
List* listLoc = t.table[position];
if ((int) listLoc == 0) {
return -1;
}
Node curr = *(listLoc -> head);
while (curr.next != NULL) {
if (curr.savedAge == key.age && curr.savedName == key.name) {
return curr.val;
}
curr = *curr.next;
}
return -1;
}
int hash(Person* p) {
int sum;
Person person = *p;
int i = 0;
char nameChar = person.name[i];
while (nameChar != '\0'){
sum += (int) nameChar;
i += 1;
nameChar = person.name[i];
}
return (int) (person.age + sum);
}
int main() {
Person bob = person(36, "Robert");
printf(bob.name);
printf("\n");
HashTable tab = table();
tab = tableAdd(tab, bob, 3);
printf("Added Robert to table as 3\n");
int val = tableGet(tab, bob);
if (val == 3) {
printf("Success!\n");
} else {
printf("Failure, val is %d\n", val);
}
return 0;
}

linked list inside a linked list segmentation error

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
struct smallnode{
char name[4];
struct smallnode *next;
};
struct bignode {
int no;
struct smallnode *element;
struct smallnode *ehead;
struct bignode *next;
};
struct bignode *classes;
struct bignode *head;
void add_class(int no){
struct bignode *newclass = malloc(sizeof(struct bignode));
newclass->no=no;
newclass->element=NULL;newclass->ehead=NULL;
if(head==NULL){classes = newclass;head = classes;head->next=NULL;}
else{
head->next=newclass;
head = head->next;
head->next=NULL;
}
}
void add_student(int noc,char* name){
struct bignode *pointer;
pointer = classes;
int i;
// get the desired class
for(i=2;i<=noc;i++){
pointer=pointer->next;
}
//add student to class
struct smallnode *newstud;
newstud = malloc(sizeof(struct smallnode));
strcpy(newstud->name,name);
if(pointer->element==NULL){
pointer->element=newstud;
pointer->ehead = pointer->element;
pointer->ehead->next=NULL;
}
else{
pointer->ehead->next=newstud;
pointer->ehead = pointer->ehead->next;
pointer->ehead->next=NULL;
}
}
void resetdata(){
struct bignode *classpointer;
struct bignode *t;
struct smallnode *studentpointer;
struct smallnode *c;
classpointer = classes;
while(classpointer!=NULL){
t=classpointer;
studentpointer=classpointer->element;
while(studentpointer!=NULL){
c = studentpointer;
studentpointer= studentpointer->next;
free(c);
}
classpointer=classpointer->next;
free(t);
}
classes = NULL;
head = NULL;
}
int main()
{
FILE *fp,*op;
int sclasw=0;int adstud=0; int noc=1;int cp=0; char c; char sname[4]=""; int sc=0;
int cases;
classes = NULL;
head = NULL;
fp = stdin;
op = stdout;
if (fp == NULL){
printf("null");
}
cases =fgetc(fp)-'0';
fgetc(fp);
//reading
int i;
for(i=1;i<=cases;i++){
c = fgetc(fp);
while(c!='\n'){
c = fgetc(fp);
if(c==':'){sclasw=1;}
else if (c=='('&&sclasw==0){adstud=1;}
else if (c=='('&&sclasw==1){}
else if (c==')'&&sclasw==1){sclasw=0;add_class(noc);}
else if (c==')'&&adstud==1){adstud=0;add_student(cp,sname);sc=0;}
else if (sclasw==1&&c==','){
add_class(noc);
noc++;
}
else if (c==','&&adstud==1){
add_student(cp,sname);
sc=0;
}
else if (c==','&&sclasw==0&&adstud==0){
cp++;sc=0;
}
else if(adstud==1){
sname[sc]=c;
sc++;
}else if(sclasw==1){/*printf("-");*/}
}
//end reading
//coloring algo
struct bignode *classpointer;
struct bignode *classpointer2;
struct smallnode *studentpointer;
struct smallnode *studentpointer2;
int *color, totalcolor;
color=malloc((noc+1)*sizeof(int));
color[1]=1; totalcolor = 1;
int col,oldcol;
//breaker
int b1=0,b2=0,b3=0;
classpointer = classes->next;
while(classpointer!=NULL){
for(col=1;col<=totalcolor;){
color[classpointer->no]=col;
oldcol=col;
studentpointer = classpointer->element;
while (studentpointer!=NULL){//for the nth element
classpointer2 = classes;
while(classpointer2!=classpointer){//check the class
if (color[classpointer2->no]==col){
studentpointer2 = classpointer2->element;
while (studentpointer2!=NULL){// for an element
if(strcmp(studentpointer->name,studentpointer2->name)==0){//that has the same student as the nth element
col++;//if theres the same student next color
color[classpointer->no]=col;
if(col>totalcolor){//if there is no next color create one
totalcolor++;b1=1;
}
b2=1;
b3=1;
break;
}
studentpointer2 = studentpointer2->next;
}
}
classpointer2=classpointer2->next;
if(b3==1){b3=0;break;}
}
studentpointer = studentpointer->next;
if(b2==1){b2=0;break;}
}
if (color[classpointer->no]==oldcol){break;}
if(b1==1){b1=0;break;}
}
classpointer=classpointer->next;
}
//end algo
fprintf(op,"Case %i: (",i);
classpointer=classes;
while(classpointer!=NULL){
fprintf(op,"C%02i:%i",classpointer->no,color[classpointer->no]);
classpointer=classpointer->next;
if(classpointer!=NULL)fprintf(op,", ");
}
fprintf(op,")\n");
resetdata();
sclasw = 0; adstud = 0; noc=1;cp=0;sc = 0;
}
return 0;
fclose(fp);
fclose(op);
}
//EDIT
Input:
1
Case 1: (C01,C02,C03,C04,C05,C06,C07,C08,C09,C10,C11),(RDA,ALB,NAC,EDF,BMG,VLJ,IVL,LGM,EGN,KSO,EST,VIV),(MCA,EDF,SLF,ADG,BCG,AAI,RRK,LGM,RLM,JGP,LRQ,WAR,KLS,DDY),(ABC,BBD,GCF,ADG,AKL,BCL,MIN,JGP,RSQ,DBU,IEY,RAW,ESZ),(ANA,JCA,CAB,NAC,GCF,GLH,VLJ,LLM,MAN,PEP,PQQ,ERR,SET,MAV,REW),(BBC,EDD,HSE,EST,ELG,ISH,JEI,EMJ,RRK,TPL,RER,EPS,AVU,CDW,ELY),(ALA,MCA,ABB,BCF,GLH,AKL,HGN,RON,JGP,ALQ,EPR,ABT,KEV,YEZ),(CDC,ISH,ABI,DHJ,ESM,FBM,RMN,PEP,VIR,JLS,LOT,MAV,TEX),(AAA,HLA,BBD,WRE,ECG,HLH,DHJ,RON,TSO,PQQ,MBT,REW,BAX,TRY,BDZ),(MCA,JCA,BCF,EGG,AAI,XTK,WIL,CSM,HLO,RSP,APR,RER,JET,DBU),(RDA,BBB,CLC,ECG,MNH,EMJ,JOK,ARM,NFM,EGN,RCN,RSP,LEQ,YIR,AVU),(ADB,WDB,BKC,CLC,SDE,UKF,BMG,HRH,BTK,LGM,QJP,EPS,KLS,BST,YNZ)
Output(in codeblocks which works just fine):
Case 1: (C01:1, C02:2, C03:1, C04:2, C05:3, C06:3, C07:1, C08:4, C09:4, C10:2, C11:4)
PS. I've already edited my source code such that there are no minor mistakes like insufficient memory for array.
This program does graph coloring by using 2 arrays. One for the classes and the other or student. The bigger linked list, which is the one for classes, has an element of a smaller linked list in each node;
Hackerrank's compiler says that it has a segmentation error, but it works fine when I run it in code blocks.
I've been stuck with this for days and I dont have any clue why this is happening. Please help me :(

Link another structure in C

I am trying to do this data stucture in C. Connect another structure to another structure. Like this:
struct room
{
int roomnumber;
struct room * nextRoom;
struct person * personList;
}*top=NULL,*temp=NULL,top1;
struct person
{
int personnumber;
struct person *next;
}*node=NULL,temp1;
Struct room has a pointer to struct person. I am having a hard time on connecting it to another struct. Is this correct?
Here is my function
void insert()
{
int val;
printf("enter value: ");
scanf("%d",&val);
newnode=create_node(val);
if(top->personList==NULL)
{
top->personList=newnode;
}
else
{
node->next=newnode;
node=newnode;
}
}
Insert a person to the room. Room is like created already. create_node() is the one who does the malloc()
Here's a version that doesn't use globals, which makes your functions much more general and reusable:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct person
{
int personNumber;
struct person *next;
} person; /* NOTE: this is a typedef, not a global declaration like you did */
typedef struct room
{
int roomNumber;
person *personList;
person *lastInList;
struct room *nextRoom;
} room; /* NOTE: this is a typedef, not a global declaration like you did */
person *create_person(int val)
{
person *ret = calloc(1, sizeof(*ret));
if (ret)
{
ret->personNumber = val;
ret->next = NULL;
}
return ret;
}
int room_insert(room *r, int val)
{
person *p = create_person(val);
if (NULL == p)
return -1;
if (NULL != r->personList)
r->lastInList->next = p;
else
r->personList = p;
r->lastInList = p;
return 0;
}
int main(int argc, char **argv)
{
room my_room = { 0 }; /* important! initializes pointers to NULL */
room my_other_room = { 0 }; /* important! initializes pointers to NULL */
person *p;
room_insert(&my_room, 5);
room_insert(&my_other_room, -5);
room_insert(&my_room, 10);
room_insert(&my_other_room, -10);
room_insert(&my_room, 15);
room_insert(&my_other_room, -15);
for (p = my_room.personList; p; p = p->next)
printf("%d\n", p->personNumber);
for (p = my_other_room.personList; p; p = p->next)
printf("%d\n", p->personNumber);
return 0;
}

Seg Fault in BST inorder traversal

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define n 5
struct node
{
int num;
char *symbol;
char *code;
struct node *left;
struct node *right;
}*root_ptr, *current, *previous;
void form_bst_of_dividing_positions();
void inorderTraversal(struct node *);
int dividing_positions[n], counter = 0;
int main(int argc, char *argv[])
{
//code to populate dividing_positions
//tree structure formation
counter = 0;
root_ptr = malloc(sizeof(struct node));
root_ptr->num = dividing_positions[0];
root_ptr->code = root_ptr->symbol = NULL;
root_ptr->left = root_ptr->right = NULL;
form_bst_of_dividing_positions();
inorderTraversal(root_ptr);
return 0;
}
void form_bst_of_dividing_positions()
{
for(i=1;i<n;i++)
{
if(dividing_positions[i]==-1)
break;
else
{
struct node nodeToAdd;
nodeToAdd.num = dividing_positions[i];
nodeToAdd.code = nodeToAdd.symbol = NULL;
nodeToAdd.left = nodeToAdd.right = NULL;
current = previous = root_ptr;
while(current!=NULL)
{
previous = current;
current = (dividing_positions[i]<(current->num))? current->left : current->right;
}
if(nodeToAdd.num<(previous->num))
previous->left = &nodeToAdd;
else
previous->right = &nodeToAdd;
}
}
}
void inorderTraversal(struct node *no)
{
if(no!=NULL)
{
inorderTraversal(no->left);
printf("%d ", no->num);
inorderTraversal(no->right);
}
}
Above code gives me Segmentation fault .. in Codeblocks the output window prints 4 infinitely. 2, 3, 1, 4 = to be inserted into BST. Ive converted my Java code to C, are there any specifics to be handled in my above code?
Thanks..
Your nodeToAdd is a local variable, its address becomes invalid once you leave that code block. You should use malloc to create new nodes (and free them with free eventually).
Use malloc everytime you add a new node.

C - pointer to struct to array of pointers

I have a linked list with a hash table in each node. The hash table is implemented by an array of pointers to structs. The whole management of this is made by a global static pointer to the linked list.
I changed a little bit the question! Now the question is more focused.
in the lookup and insert function to make the code shorter I assign
temp = cur_table->symbols_table[entry];
but I see that temp gets NULL all the time.
I can't understand why is that happens?
The code is below in 3 modules.
Thank you in ahead.
symbols.h file:
#include <stdlib.h>
#include <stdio.h>
#define TABLE_SIZE 26
typedef struct symbol_node
{
char* name;
int type;
int role;
struct symbol_node* next;
} symbol_node;
typedef struct table_node
{
struct symbol_node* symbols_table[TABLE_SIZE];
struct table_node* prev;
struct table_node* next;
} table_node;
static struct table_node* cur_table;
//functions declarations:
void init_table();
int hash_function(char* id);
symbol_node* lookup(char* id_name);
symbol_node* insert(char* id_name);
// debug
void printtable();
symbols.c
void init_table() // creates the first node
{
int i = 0;
cur_table = NULL;
cur_table = (table_node*)malloc(sizeof(table_node));
cur_table->prev = NULL;
cur_table->next = NULL;
for(i=0; i < TABLE_SIZE; i++)
{
cur_table->symbols_table[i] = NULL;
}
}
symbol_node* lookup(char* id_name) // returns null if the id name not found
{
symbol_node* result = NULL;
symbol_node* temp = NULL;
int entry = atoi(id_name);
temp = cur_table->symbols_table[entry];
while(temp != NULL)
{
if( strcmp( id_name, temp->name ) == 0 )
{
result = temp;
break;
}
else
temp = temp->next;
}
return result;
}
symbol_node* insert(char* id_name)
{
symbol_node* result = NULL;
symbol_node* temp = NULL;
int index = -1;
if(lookup(id_name)==NULL)
{
index = atoi(id_name);
temp = cur_table->symbols_table[index];
while(temp!=NULL)
{
temp = temp->next;
}
temp = (symbol_node*)malloc(sizeof(symbol_node));
temp->next = NULL;
temp->name = id_name;
// TODO: other params
result = temp;
}
return result;
}
void printtable()
{
int i=0;
for(i=0; i<TABLE_SIZE; i++)
{
if(cur_table->symbols_table[i]==NULL)
printf("NULL at index %d\n",i);
else
printf("There are something\n");
}
}
main.c
void main()
{
int i=0;
symbol_node* t = NULL;
symbol_node* tt = NULL;
init_table();
t = insert("markhit");
t = insert("mark");
tt = lookup("mark");
printtable();
_getch();
free(t);
free(tt);
free(cur_table);
}
avoid memory allocation [`malloc'] statically. try it
cur_table = new table_node;
for statically allocated memory, you can not set your value for memory reason. when you are inserting it is not reallocating your cur_table

Resources