Issue with Adjacency List in C - c

I'm trying to insert nodes in a graph using a adjacency list, but it just crashes when i try to insert this line
criaEstacao("Edgware Road", "Verde, Rosa", 200, 0);
on main(). If there is only one insertion it works.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max 20
#define TRUE 1
#define FALSE 0
typedef struct no{
char nome[100];
char linhas[100];
int distancia;
int manutencao;
struct no *prox;
struct no *ant;
} No;
No *LinhaAmarela[max];
No *criaEstacao(char n[100], char l[100], int d, int m){
int i = 0;
No *novo = (No*)malloc(sizeof(No*));
strcpy(novo->nome, n);
strcpy(novo->linhas, l);
novo->distancia = d;
novo->manutencao = m;
novo->prox = NULL;
novo->ant = NULL;
while (LinhaAmarela[i] != NULL && i < max){
i++;
}
LinhaAmarela[i] = novo;
}
int main() {
criaEstacao("Paddington", "Verde, Rosa, Marrom", 200, 0);
criaEstacao("Edgware Road", "Verde, Rosa", 200, 0);
getch();
}

Allocate memory for the struct, not the pointer:
No *novo = malloc(sizeof(No));
of better:
No *novo = malloc(sizeof(*novo));
And always check the return value.

Related

Segmentation fault on separate chaining hashtable

So i implemented a hashtable with separate chaining for a struct called Objective, so that i could perform some operations on said Objectives. Currently i have this:
Hashtable.h:
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/*Using separate chaining to store the obejctives*/
typedef struct Objective{
char name [8000];
unsigned long id, duration, deps [9000];
int hasDeps;
}*pObjective;
typedef struct nodehash{ /*Node of list*/
pObjective obj;
struct nodehash*next;
}*link;
void Init(int M);
int search(unsigned long id);
void insert(pObjective o);
void delete(unsigned long id);
link insertBegin(link h, pObjective obj);
int searchList(link h, unsigned long id);
link removeList(link h, unsigned long id);
pObjective searchObj(unsigned long id);
pObjective searchObjAux(link h, unsigned long id);
#endif
Objectives.c:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "OBJECTIVES.h"
/*Checks if all inserted dependencies already exist*/
int existDeps(unsigned long dep[9000]){
int i, count = 0;
for(i = 0; i < 9000; i++){
if(search(dep[i]) != 0)
count++;
}
return count;
}
/ *Adds objective with dependencies*/
void addObj(unsigned long id, char name [8000], unsigned long duration,
unsigned long dep[9000]){
int i;
pObjective obj = malloc(sizeof(pObjective));
obj->id = id;
obj->duration = duration;
obj->hasDeps = 1;
strcpy(name, obj->name);
for(i = 0; i < 9000; i++){
obj->deps[i] = dep[i];
}
if(search(id) != 0)
printf("id already exists\n");
else if(existDeps(dep) != 0)
printf("no such task\n");
else
insert(obj);
free(obj);
}
/*Adds objective with no dependencies*/
void addNoDeps(unsigned long id, char name [8000], unsigned long
duration){
pObjective obj = malloc(sizeof(pObjective));
obj->id = id;
obj->duration = duration;
obj->hasDeps = 1;
strcpy(name, obj->name);
if(search(id) != 0)
printf("id already exists\n");
else
insert(obj);
free(obj);
}
/*Removes objective with no dependencies*/
void removeObj(unsigned long id){
int res = search(id);
pObjective obj = searchObj(id);
if(res == 0)
printf("no such task\n");
else if(obj->hasDeps == 1)
printf("task with dependencies\n");
else
delete(id);
}
Objectives.h:
#ifndef OBJECTIVES_H
#define OBJECTIVES_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "HASHTABLE.h"
/*Functions to work with objectives*/
int existDeps(unsigned long dep[9000]);
void addObj(unsigned long id, char name [8000], unsigned long duration,
unsigned long dep[9000]);
void addNoDeps(unsigned long id, char name [8000], unsigned long
duration);
void removeObj(unsigned long id);
#endif
Hashtable.c:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "HASHTABLE.h"
#define hash(A,B) (A%B) /*Hash function*/
static link *heads;
static int M;
/*Initiates hashtable with size m*/
void Init(int m){
int i;
M = m;
heads = (link*)malloc(M*sizeof(link));
for(i = 0; i < M; i++)
heads[i] = NULL;
}
/*Searches objective with said id*/
int search(unsigned long id){
int i = hash(id, M);
return searchList(heads[i], id);
}
/*Inserts objective into hashtable*/
void insert(pObjective o){
int i = hash(o->id, M);
heads[i] = insertBegin(heads[i], o);
}
/*Deletes objective using it's id*/
void delete(unsigned long id){
int i = hash(id, M);
heads[i] = removeList(heads[i], id);
}
/*Returns objective with said id*/
pObjective searchObj(unsigned long id){
int i = hash(id, M);
return searchObjAux(heads[i], id);
}
/*Inserts objective into list*/
link insertBegin(link h, pObjective obj){
link new = (link)malloc(sizeof(struct nodehash));
new->obj = obj;
new->next = h;
return new;
}
/*Searches objective by id in a list*/
int searchList(link h, unsigned long id){
link t;
int count = 0;
for(t = h; t != NULL; t = t->next){
if(t->obj->id == id)
count++;
}
return count++;
}
/*Removes objective from list*/
link removeList(link h, unsigned long id){
link t, x, z;
for(t = h; t != NULL; t = t->next){
if(t->next->obj->id == id)
x = t;
}
z = x->next;
x->next = z->next;
free(z);
return h;
}
/*Returns objetive from said id from list*/
pObjective searchObjAux(link h, unsigned long id){
link t, x;
for(t = h; t != NULL; t = t->next){
if(t->obj->id == id)
x = t;
}
return x->obj;
}
I'm quick testing the funcions addObj (adds an objective with dependencies) and addNoDeps (adds an objective with no dependencies) on my main:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "OBJECTIVES.h"
int main(){
unsigned long array [1] = {3};
Init(11);
addNoDeps(1, "tarefa1", 20);
addObj(2, "tarefa2", 20, array);
return 0;
}
But i keep getting segmentation fault(core dumped) and i can't figure out why. Is my implementation wrong? Are the functions wrong? I can't get to the problem, can someone help me?
I can't run your code right now so I can't analyze the core dump, but I believe what is happening is that you are trying to access memory that has already been freed. At the end of addNoDeps, you free the pObjective after putting it into the list. Then, when you addObj after, you search the list and check to make sure that the links object associated with it is not null. Specifically this code:
for(t = h; t != NULL; t = t->next){
if(t->obj->id == id)
count++;
You only check to see that the t (links pointer) is not null, but since you freed the previous object, the t->obj pointer is not pointing to initialized memroy. Therefore trying to access it via t->obj->id is accessing uninitialized memory. If you remove the free(obj) at the end of your addNoDeps and addObj functions you should be fine. You may also want to add checks to make sure that t->obj is not null as well. In general segmentation faults are caused by accessing uninitialized memory, so when debugging check for accessing pointers after a free, double frees, and other things. Also learning to use GDB can help a lot in these situations.

C Memory Management -> Hash

I don't know if my problem is a memory leak, or i'm not acessing the hashtable in the correct way.
My hash.h
#define HASHSIZE 31
#define EMPTY ""
#define DELETED "-"
typedef char KeyType[9];
typedef void *Info;
typedef struct entry
{
KeyType key;
Info info;
}Entry;
typedef Entry HashTable[HASHSIZE];
My hash.c
int Hash(KeyType k){
return atoi(k)%HASHSIZE;
}
void InitializeTable(HashTable t){
for(int i=0; i < HASHSIZE; i++){
strncpy(t[i].key,EMPTY,9);
}
}
void ClearTable(HashTable t){
InitializeTable(t);
}
void InsertTable_LP(HashTable t, KeyType k, Info i){
int a = 0;
int hash = Hash(k);
while((a<HASHSIZE)
&& strcmp(t[hash].key,EMPTY)!=0
&& strcmp(t[hash].key,DELETED)!=0 ){
hash = (hash + 1) % HASHSIZE;
a++;
}
strncpy(t[hash].key,k,9);
t[hash].info = i;
printf("Value of info is %d\n",(int)t[hash].info);
}
int RetrieveTable_LP(HashTable t, KeyType k){
int a=0;
int hash = Hash(k);
while(a<HASHSIZE
&& strcmp(t[hash].key,k)!=0
&& strcmp(t[hash].key,EMPTY)!=0){
hash=(hash+1) % HASHSIZE;
a++;
}
if(strcmp(t[hash].key,k)==0)
return hash;
return -1;
}
int main(){
HashTable *t = malloc(HASHSIZE*sizeof(Entry));
int valores[] = {1,2,3,4,5,6,7,8,9};
ClearTable(*t);
InsertTable_LP(*t,"1",valores);
InsertTable_LP(*t,"2",valores+1);
InsertTable_LP(*t,"3",valores+2);
InsertTable_LP(*t,"4",valores+3);
InsertTable_LP(*t,"5",valores+4);
int pos = RetrieveTable_LP(*t,"2");
if(pos==-1){
printf("Error\n");
}
else
printf("Position %d\n",pos);
printf("okay %d\n",(int)t[pos]->info);
printf("asdasdas\n");
return 1;
}
My output is
Value of info is 1537727040
Value of info is 1537727044
Value of info is 1537727048
Value of info is 1537727052
Value of info is 1537727056
Position 2
okay 0
If anyone could explain me, thanks in advance.
valores is an array. You are inserting Info which has been typedefed to void *. You need to fix those things.
Your malloc is not necessary the reason why that wasn't obvious is because it was hidden by the way you typedefd the HashTable, don't ever do that, the following code works as you expected yours to do
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HASHSIZE 31
#define EMPTY ""
#define DELETED "-"
typedef char KeyType[9];
typedef void *Info;
typedef struct entry
{
KeyType key;
Info info;
}Entry;
typedef Entry HashTable[HASHSIZE];
int Hash(KeyType k){
return atoi(k)%HASHSIZE;
}
void InitializeTable(HashTable t) {
int i;
for(i=0; i < HASHSIZE; i++) {
strncpy(t[i].key, EMPTY, 9);
}
}
void ClearTable(HashTable t) {
InitializeTable(t);
}
void InsertTable_LP(HashTable t, KeyType k, Info i){
int a = 0;
int hash = Hash(k);
while((a<HASHSIZE) && strcmp(t[hash].key, EMPTY) !=0 && strcmp(t[hash].key, DELETED) !=0 ) {
hash = (hash + 1) % HASHSIZE;
a++;
}
strncpy(t[hash].key, k, 9);
t[hash].info = i;
printf("Value of info is %p\n", t[hash].info);
}
int RetrieveTable_LP(HashTable t, KeyType k){
int a=0;
int hash = Hash(k);
while(a<HASHSIZE
&& strcmp(t[hash].key,k)!=0
&& strcmp(t[hash].key,EMPTY)!=0){
hash=(hash+1) % HASHSIZE;
a++;
}
printf("%s, %s\n", t[hash].key, k);
if(strcmp(t[hash].key, k)==0)
return hash;
return -1;
}
int main(){
/*
* You don't need to malloc, since HashTable is an array,
* and it does not need to be a pointer, since it decays
* to one when passed as such.
*/
HashTable t;// = malloc(HASHSIZE * sizeof(Entry));
int valores[] = {1,2,3,4,5,6,7,8,9};
ClearTable(t);
InsertTable_LP(t,"1",valores);
InsertTable_LP(t,"2",valores+1);
InsertTable_LP(t,"3",valores+2);
InsertTable_LP(t,"4",valores+3);
InsertTable_LP(t,"5",valores+4);
int pos = RetrieveTable_LP(t, "2");
if(pos==-1) {
printf("Error\n");
}
else
{
printf("Position %d\n",pos);
printf("okay %p\n", t[pos].info);
}
printf("asdasdas\n");
return 1;
}
your typedef of the HashTable makes it hard to know what to do with a HashTable type variable, that is not a very good use of typedef.
Also the second printf will be executed regardless of the condition
else
printf("Position %d\n",pos);
printf("okay %d\n",(int)t[pos]->info);
you need to add {
else
{
printf("Position %d\n",pos);
printf("okay %d\n",(int)t[pos]->info);
}

Thread not working properly - C

I've made a queue header file and I've tried to use it with threads.
What I'm doing is making 2 threads, 1 for reading the characters from the code file and entering the characters to the queue and the other thread is trying to print the characters to the console.
The problem is that no characters are being printed to the console and I can't figure out why.
queue.h :
#ifndef QUEUE_INT
#define QUEUE_INT
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct
{
int *elementData;
unsigned int queueSize;
unsigned int capacityIncrement;
unsigned int elementCount;
} Queue;
void queue_initialize(Queue*, unsigned int);
int queue_add(Queue*, int);
void queue_poll(Queue*);
int queue_peek(const Queue*);
void queue_destroy(Queue*);
bool queue_isEmpty(const Queue*);
void queue_setCapacityIncrement(Queue*, unsigned int);
unsigned int queue_getCapacityIncrement(const Queue*);
unsigned int queue_getNumberOfElements(const Queue*);
unsigned int queue_getSize(const Queue*);
void queue_initialize(Queue *p, unsigned int capacityIncrement)
{
p->elementData = NULL;
p->queueSize = 0;
p->capacityIncrement = capacityIncrement;
p->elementCount = 0;
}
int queue_add(Queue *p, int value)
{
if(p->elementCount == p->queueSize)
{
int newQueueSize = p->queueSize + p->capacityIncrement;
void *temp = realloc(p->elementData, sizeof(*p->elementData) * newQueueSize);
if(temp == NULL || newQueueSize == 0)
{
return 1;
}
p->queueSize = newQueueSize;
p->elementData = temp;
}
p->elementData[p->elementCount] = value;
p->elementCount++;
return 0;
}
void queue_poll(Queue *p)
{
if(!queue_isEmpty(p))
{
p->elementCount--;
if(p->queueSize - p->elementCount == p->capacityIncrement / 2 + p->capacityIncrement)
{
int newQueueSize = p->queueSize - p->capacityIncrement;
p->elementData = realloc(p->elementData, sizeof(*p->elementData) * newQueueSize);
p->queueSize = newQueueSize;
}
for(int i = 0; i < p->elementCount; i++)
{
p->elementData[i] = p->elementData[i + 1];
}
}
}
int queue_peek(const Queue *p)
{
if(!queue_isEmpty(p))
{
return p->elementData[0];
}
return 0;
}
void queue_destroy(Queue *p)
{
free(p);
}
bool queue_isEmpty(const Queue *p)
{
return p->elementCount == 0;
}
void queue_setCapacityIncrement(Queue *p, unsigned int capacityIncrement)
{
p->capacityIncrement = capacityIncrement;
}
unsigned int queue_getCapacityIncrement(const Queue *p)
{
return p->capacityIncrement;
}
unsigned int queue_getNumberOfElements(const Queue *p)
{
return p->elementCount;
}
unsigned int queue_getSize(const Queue *p)
{
return p->queueSize;
}
#endif
Code file :
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <process.h>
#include <time.h>
#include "queue.h"
bool isFillQueueThreadRunning;
bool isQueueProcessing;
void fillQueueThread(void*);
void popQueueThread(void*);
int main()
{
srand(time(NULL));
Queue q1;
queue_initialize(&q1, 4);
HANDLE hFillQueueThread = (HANDLE)_beginthread(fillQueueThread, 0, (void*)&q1);
HANDLE hPopQueueThread = (HANDLE)_beginthread(fillQueueThread, 0, (void*)&q1);
WaitForSingleObject(hFillQueueThread, 1000 * 300);
WaitForSingleObject(hPopQueueThread, 1000 * 300);
return 0;
}
void fillQueueThread(void *p)
{
isFillQueueThreadRunning = true;
Queue *q = (Queue*)p;
FILE *f = fopen(__FILE__, "r");
int b;
while((b = getc(f)) != EOF)
{
Sleep(rand() % 50);
while(isQueueProcessing)
{
}
isQueueProcessing = true;
if (queue_add(q, b) == 1)
{
break;
}
isQueueProcessing = false;
}
fclose(f);
isFillQueueThreadRunning = false;
}
void popQueueThread(void *p)
{
Queue *q = (Queue*)p;
Sleep(10);
int b;
while(isFillQueueThreadRunning || q->elementCount > 0)
{
while(isQueueProcessing)
{
}
isQueueProcessing = true;
b = queue_peek(q);
queue_poll(q);
putchar(b);
isQueueProcessing = false;
}
}
you _beginthread the fillQueueThread twice.
and
you never initialize isFillQueueThreadRunning reliably. Code may depend on uninitialized variable.
from what I've seen
Your queue implementation is far from thread safe. As Joachim mentioned, please education yourself with thread synchronization primitives. A simple mutex would go a long way here.
See: What is a mutex?
As to your large blocks of spaces, you use the output of queue_peek() unconditionally which can (and will frequently) be NULL.
Do you know that the result of putchar(NULL) is?

Hash Tables program crashes

I wonder if I'm doing something wrong in my program.
I manage to create a HashTable but when I send it through parameter to my displayingList() function, it crashes.
source.c (contains my functions):
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#include "header.h"
#define MAX 255
int countLetters(char myStr[])
{
int myLen = strlen(myStr), i;
int wordLen = 0;
for (i = 0 ; i < myLen; ++i)
{
wordLen += (int)(myStr[i]);
}
return (wordLen%256);
}
void populateList(NodeT *T[255], char myStr[])
{
NodeT *p, *q;
p = (NodeT *)malloc(sizeof(NodeT));
strcpy (p->key, myStr);
int myPos = countLetters(myStr);
if(T[myPos] == NULL)
{
p->next = NULL;
T[myPos] = p;
}
else
{
q = T[myPos];
p->next = q;
T[myPos] = p;
}
}
void displayList(NodeT *T[255])
{
int i;
NodeT *p;
for(i = 0 ; i < 255; ++i)
{
if(T[i] != NULL)
{
printf("Index: %d - Data:", i);
p = T[i];
while(p != 0)
{
printf("%s, ", p->key); // HERE IT CRASHES.
p = p->next;
}
printf("\n");
}
}
}
main.c (contains the int main()):
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
int main(void)
{
NodeT *T[255];
int n, i;
printf("Give no. of elements:");
scanf("%d", &n);
fflush(stdin);
for(i = 0 ; i < n ; ++i)
{
char name[100];
gets(name);
populateList(T, name);
}
displayList(T);
return 0;
}
header.h (and my header):
#ifndef HEADER_H
#define HEADER_H
typedef struct cell
{
char key[100];
struct cell *next;
}NodeT;
int countLetters(char myStr[]);
void populateList(NodeT *T[], char myStr[]);
void displayList(NodeT *T[]);
#endif // HEADER_H
I tried to see what exactly happens with debugger and it seems that when I send T[] list to displayList() function, actually it doesn't have the same structure as it has in main.c.
ISSUE: the insertion works fine, but when I try to display my list (on each index) it crashes.
Any ideas?
Thanks in advance.
The possible solution is to declare the NodeT *T[255] global. However it isn't the best practice at all.

Array of Structs strange output?

Can anyone give me some indication as to why array of structs doesn't print out properly ?
I think its something to do with the memory I have allocated to the struct I am unsure !!
Using mac osx mountain lion xcode 4 gcc
Thanks for any help completely stuck!!
(Please have patience I am only a student !)
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
typedef struct{
char* one;
char* two;
} Node;
Node *nodes;
int count = 0;
//-----------------------------------------------------------------------
void add(char *one,char*two){
char x[40];
char y[40];
printf("reached..\n");
strcpy(x,one);
strcpy(y,two);
printf("--> X: %s\n",x);
printf("--> Y: %s\n",y);
Node newNode;
newNode.one = x;
newNode.two = y;
nodes[count]= newNode;
count++;
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void print(){
int x;
for (x = 0; x < 10; x++)
{
printf("%d : (%s, %s) \n",x,nodes[x].one, nodes[x].two);
}
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void check(char **arg)
{
if(strcmp(*arg, "Add") == 0)
{
add(arg[1],arg[2]);
}else if(strcmp(*arg,"print") == 0)
{
print();
}else{
printf("Error syntax Enter either: \n Add [item1][item2]\n OR \n print\n");
}
}
//-----------------------------------------------------------------------
void readandParseInput(char *line,char **arg)
{
if (fgets (line, 512, stdin)!= NULL) {
char * pch;
pch = strtok (line," \n\t");
int count = 0;
arg[0] = pch;
while (pch != NULL)
{
count++;
pch = strtok (NULL, " \n\t");
arg[count] =pch;
}
}else{
printf("\n");
exit(0);
}
}
//-----------------------------------------------------------------------
int main()
{
int size = 100;
nodes = calloc(size, sizeof(Node));
int i;
for(i = 0;i <100; i++){
printf("%s , %s \n",nodes[i].one,nodes[i].two );
// nodes[i].one = ".";
// nodes[i].two = ".";
}
char line[512]; /* the input line */
char *arg[50]; /* the command line argument */
while (1)
{
readandParseInput(line,arg);
if(arg[0] != NULL){
check(arg);
}
}
return(0);
}
You're keeping pointers to the following automatic variables:
char x[40];
char y[40];
These go out of scope when add() returns, leaving you with dangling pointers.
You either have to turn Node::one and Node::two into arrays, or allocate memory for them on the heap.
In you add() function, you cannot assign one struct to another via an = operator... you would have to copy it...
memcpy( &nodes[count], &newNode )
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *fn;
}NAME;
#define NAME_LEN 20
int main()
{
NAME name;
name.fn = (char *) calloc(NAME_LEN, sizeof(char));
strcpy(name.fn, "Namco");
printf("Name: %s\n", name.fn);
free(name.fn);
return 0;
}
you can't just assign a string like this in c
newNode.one = x;
newNode.two = y;
what is newNode.one referring to???
at Function add
newNode.one = x;
newNode.two = y;
to
newNode.one = strdup(x);
newNode.two = strdup(y);

Resources