Following this tutorial on Hash Tables, I implemented a sort of simplified version. However, whenever delete_entry is called on every 4th index(4,8,12...), I get a segmentation fault. Else, it works fine
Here's the code I run:
#include <stdio.h>
typedef struct {
int key;
int value;
} entry;
typedef struct{
int length;
int count;
entry** items;
} table;
entry *new_entry(const int, const int);
table *create_table();
void destroy_table(table *t);
void delete_entry(entry *e);
void table_insert(table *, const int, const int);
int main(){
table *new_table = create_table();
printf("[INFO] Created new table successfully!!\n");
for(int i=0; i<16; i++){
table_insert(new_table,i,i+i);
}
printf("[INFO] Inserted %d items\n",new_table->count);
destroy_table(new_table);
printf("[INFO] Destroyed table successfully!!\n");
return 0;
}
table *create_table(){
table *new_table = malloc(sizeof(table));
if(new_table == NULL){
printf("[WARNING] Malloc failure, returning NULL");
return NULL;
}
new_table->length = 16;
new_table->count = 0;
new_table->items = calloc((size_t)new_table->length, sizeof(entry*));
return new_table;
}
entry *new_entry(const int k, const int val){
entry *new_item = malloc(sizeof(entry));
if(new_item == NULL){
printf("[WARNING] Malloc failure, returning NULL");
return NULL;
}
new_item->key = k;
new_item->value = val;
return new_item;
}
void destroy_table(table *t){
for(int i=0; i<t->count; i++){
if(i== 4 || i == 8|| i==12) //Without this program terminates after 3rd index
continue;
entry *e = t->items[i];
if (e != NULL){
delete_entry(e);
}
}
free(t->items);
free(t);
}
void delete_entry(entry *e){
free(e->key);
free(e->value);
free(e);
}
void table_insert(table *t, const int k, const int v){
entry *e = new_entry(k, v);
t->items[t->count] = e;
t->count++;
}
Try to replace delete_entry() with:
void delete_entry(entry *e){
free(e);
}
Freeing values of integers e->key and e->value will likely result in Undefined Behavior. You should use free() only on objects produced by malloc() and friends.
Related
Hi am trying to create a generic list iterator that stores elements of integer or string.I am trying to test a case where it calls the IteratorG advance(IteratorG it, int n) function which takes in the list it and if n is a positive integer,it advances(moves) towards the first element by n times.If n is negative,it advances towards the last element in the list by n times.The elements are then copied to a newly created list lis and the list returned.If advancing by n times is not possible,the function returns NULL.
This is tested in test case 3 under the test cases below.
However,it is responding with a segmentation fault error and i tried using gdp to diagnose the problem and i suspect it is from the advance function at the line add(lis,&(tem->value));
This is the advance function:
IteratorG advance(IteratorG it, int n){
int zero;
zero=0;
IteratorG lis;
lis = malloc(sizeof (struct IteratorGRep));
assert (lis != NULL);
lis->numofit = 0;
lis->head = NULL;
lis->tail = NULL;
lis->curr = NULL;
Node *tem;
if ((tem = malloc(sizeof(Node))) == NULL) {
return 0;
}
if(n<0 && distanceFromStart(it)!=0 )
{
for(tem=it->curr;n!=zero;it->curr=it->curr->prev)
{
add(lis,&(tem->value));
zero++;
}
return lis;
}
if(n>0 && distanceToEnd(it)!=0)
{
for(tem=it->curr;n!=zero;it->curr=it->curr->next)
{
add(lis,&(tem->value));
zero++;
}
return lis;
}
//To be implemented
//move forward by n times
return NULL;
}
I am using a Linux environment and the errors are indicative from the results. The rest of the functions that are required to test this(test in test case 3 under the test code) should be working fine.Here is the code for the whole program:
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "iteratorG.h"
typedef struct Node {
void *value; // value of thee list item
struct Node *prev;
// pointer previous node in list
struct Node *next;
// pointer to next node in list
// implemented struct here ..
} Node;
typedef struct IteratorGRep {
int numofit; // count of items in list
Node *head; // first node in list
Node *curr; // current node in list
Node *tail; // last node in list
ElmCompareFp cmpElm;
ElmNewFp newElm;
ElmFreeFp freeElm;
// implemented struct here ..
} IteratorGRep;
/*
//Your functions below ....
*/
IteratorG newIterator(ElmCompareFp cmpFp, ElmNewFp newFp, ElmFreeFp freeFp){
IteratorG newit;
if ((newit = malloc(sizeof (struct IteratorGRep)))==NULL)
{
printf("Error...! \n");
}
//assert (newit != NULL);
newit->numofit = 0;
newit->head = NULL;
newit->tail = NULL;
newit->curr = NULL;
newit->cmpElm=cmpFp;
newit->newElm=newFp;
newit->freeElm=freeFp;
return newit;
// implemented function here and changed return value
}
int add(IteratorG it, void *vp){
Node *temp;
if ((temp = malloc(sizeof(Node))) == NULL) {
return 0;
}
Node *tempe;
if ((temp = malloc(sizeof(Node))) == NULL) {
return 0;
}
temp->value = it->newElm(vp);
//temp->next=NULL;
if(it->curr==NULL)
{
//temp->next=it->curr;
it->head=it->tail=temp;
it->curr=temp;
}
else
{
tempe=it->curr;
tempe->prev=temp;
temp->next=tempe;
it->curr=tempe;
it->curr=temp;
it->head=temp;
}
//it->tail=it->head=it->curr;
return 1;
}
int hasNext(IteratorG it){
if(it->curr->next==NULL)
{
return 0;
}
// check if theres next element/node
return 1;
}
int hasPrevious(IteratorG it){
if(it->curr->prev!=NULL)
{
return 1;
}
// check if theres previous element/node
return 0;
}
void *next(IteratorG it){
Node *tempo;
if(it->curr->next==NULL)
{
return NULL;
}
tempo=it->curr;
it->curr=it->curr->next;
// implemented function here
return tempo->value;
}
void *previous(IteratorG it){
Node *tempor;
tempor=it->curr;
if(tempor->prev==NULL)
{
return NULL;
}
tempor=it->curr->prev;
it->curr=it->curr->prev;
//tempor=it->curr;
// move to next node in list
return tempor->value;
}
int del(IteratorG it){
if(it->curr->prev!=NULL)
{
Node *temp_curr=it->curr;
Node *temp_prev=it->curr->prev->prev;
temp_curr->prev=temp_prev;
temp_prev->next=temp_curr;
return 1;
}// delete previous node from list
else
return 0;
}
int set(IteratorG it, void *vp){
if(it->curr->prev!=NULL)
{
it->curr->prev->value=vp;
return 1;
}
// change previous node value with new
return 0;
}
IteratorG advance(IteratorG it, int n){
int zero;
zero=0;
IteratorG lis;
lis = malloc(sizeof (struct IteratorGRep));
assert (lis != NULL);
lis->numofit = 0;
lis->head = NULL;
lis->tail = NULL;
lis->curr = NULL;
Node *tem;
if ((tem = malloc(sizeof(Node))) == NULL) {
return 0;
}
if(n<0 && distanceFromStart(it)!=0 )
{
for(tem=it->curr;n!=zero;it->curr=it->curr->prev)
{
add(lis,tem);
zero++;
}
return lis;
}
if(n>0 && distanceToEnd(it)!=0)
{
for(tem=it->curr;n!=zero;it->curr=it->curr->next)
{
add(lis,&(tem->value));
zero++;
}
return lis;
}
//To be implemented
//move forward by n times
return NULL;
}
void reverse(IteratorG it){
Node *curr = it->head;
Node *temp = NULL;
while(curr != NULL) {
temp = curr->next;
curr->next = curr->prev;
curr->prev = temp;
curr = temp;
}
temp = it->head;
it->head = it->tail;
it->tail = temp;// reverse elements of whole list
}
IteratorG find(IteratorG it, int (*fp) (void *vp) ){
// To be implemented
// Find elements of vp in list after current position and put in new list.return the list.
return NULL;
}
int distanceFromStart(IteratorG it){
Node *c=it->curr;
int count=0;
while(c->prev!=NULL)
{
c=c->prev;
count++;
}
return count;
// count number of elements from start of list to current position
}
int distanceToEnd(IteratorG it){
Node *cu=it->curr;
int count=0;
while(cu->next!=NULL)
{
cu=cu->next;
count++;
}
return count;
// count number of elements from end of list to current position
}
void reset(IteratorG it){
while(it->curr->prev!=NULL)
{
it->curr=it->curr->prev;
}
return;
// move current position to start of list
}
void freeIt(IteratorG it){
assert(it != NULL);
Node *curr, *prev;
curr = it->head;
while (curr != NULL) {
prev = curr;
curr = curr->next;
// free(prev->value);
free(prev);
}
free(it); // free items
}
This is the header file for the code:
#ifndef LISTITERATORG_H
#define LISTITERATORG_H
#include <stdio.h>
typedef struct IteratorGRep *IteratorG;
typedef int (*ElmCompareFp)(void const *e1, void const *e2);
typedef void *(*ElmNewFp)(void const *e1);
typedef void (*ElmFreeFp)(void *e1);
IteratorG newIterator(ElmCompareFp cmpFp, ElmNewFp newFp, ElmFreeFp freeFp);
int add(IteratorG it, void *vp);
int hasNext(IteratorG it);
int hasPrevious(IteratorG it);
void *next(IteratorG it);
void *previous(IteratorG it);
int del(IteratorG it);
int set(IteratorG it, void *vp);
IteratorG advance(IteratorG it, int n);
void reverse(IteratorG it);
IteratorG find(IteratorG it, int (*fp) (void *vp) );
int distanceFromStart(IteratorG it);
int distanceToEnd(IteratorG it);
void reset(IteratorG it);
void freeIt(IteratorG it);
#endif
One of the functions have yet to be implemented and is indicated in the code itself. But I guess that might not be the source of issue here.
EDIT:
heres the test case code. Theres no errors in the test case code just in the program above only :
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "iteratorG.h"
#include "positiveIntType.h"
#include "stringType.h"
#define MAXARRAY 5
/* Helper Functions Below */
/* Returns 1 if marks >= 50, 0 otherwise */
int passMarks(void *marks){
return (*((int *) marks) >= 50);
/* Easy to understand below ..
int *ip = (int *) marks;
if(*ip >= 50) { return 1; }
else { return 0; }
*/
}
/* Returns 1 if str starts with "jo" */
int prefixJo(void *str){
return (strncmp("jo", (char *) str, 2) == 0) ;
}
/* A function to print a string from a void pointer */
void prnStr(void *vp){
assert(vp != NULL);
printf(" %s", (char *) vp );
}
/* A function to print an integer from a void pointer */
void prnInt(void *vp){
assert(vp != NULL);
printf(" %d", *((int *) vp) );
}
/* Prints previous element using the given function 'fp'
examples: prnPrev(it1, prnInt); prnPrev(it2, prnStr);
*/
void prnPrev(IteratorG it, void (*fp) (void *p) ){
void *prevP = previous(it);
assert(prevP != NULL);
printf("> Previous value is: ");
fp(prevP);
printf("\n");
}
/* Prints next element using the given function 'fp'
examples: prnNext(it1, prnInt); prnNext(it2, prnStr);
*/
void prnNext(IteratorG it, void (*fp) (void *p) ){
void *nextP = next(it);
assert(nextP != NULL);
printf("> Next value is: ");
fp(nextP);
printf("\n");
}
/* Prints elements of 'it' from current to last position
using the given function 'fp'. The current position
of 'it' will change to the end of the list.
examples: prnIt(it1, prnInt); prnIt(it2, prnStr);
*/
void prnIt(IteratorG it, void (*fp) (void *p) ){
int count = 0;
while(hasNext(it)){
void *nextP = next(it);
count++;
if(count > 1) { printf(", "); }
fp(nextP);
}
printf("\n");
}
/* Few Tests Below */
void test1(){
printf("\n--==== Test-01 ====------\n");
IteratorG it1 = newIterator(positiveIntCompare, positiveIntNew, positiveIntFree);
int a[MAXARRAY] = { 25, 78, 6, 82 , 11};
for(int i=0; i<MAXARRAY; i++){
int result = add(it1 , &a[i]);
printf("> Inserting %d: %s \n", a[i], (result==1 ? "Success" : "Failed") );
}
freeIt(it1);
printf("--==== End of Test-01 ====------\n");
}
void test2(){
printf("\n--==== Test-02 ====------\n");
IteratorG it1 = newIterator(positiveIntCompare, positiveIntNew, positiveIntFree);
int a[MAXARRAY] = { 72, 14, 62, 8, 93};
for(int i=0; i<MAXARRAY; i++){
int result = add(it1 , &a[i]);
printf("> Inserting %d: %s \n", a[i], (result==1 ? "Success" : "Failed") );
}
prnNext(it1, prnInt);
prnNext(it1, prnInt);
prnPrev(it1, prnInt);
int newVal1 = 55;
int result1 = set(it1, &newVal1);
printf("> Set value: %d ; return val: %d \n", newVal1, result1 );
prnPrev(it1, prnInt);
freeIt(it1);
printf("--==== End of Test-02 ====------\n");
}
void test3(){
printf("\n--==== Test-03 ====------\n");
IteratorG it1 = newIterator(positiveIntCompare, positiveIntNew, positiveIntFree);
int a[MAXARRAY] = { 04, 54, 15, 12, 34};
for(int i=0; i<MAXARRAY; i++){
int result = add(it1 , &a[i]);
printf("> Inserting %d: %s \n", a[i], (result==1 ? "Success" : "Failed") );
}
reset(it1);
printf("> it1 (after reset): \n");
prnIt(it1, prnInt);
reset(it1);
IteratorG advIt1 = advance(it1, 4);
printf("> advance(it1, 4) returns: \n");
prnIt(advIt1, prnInt);
//IteratorG advIt2 = advance(it1, -3);
//printf("> advance(it1, -3) returns: \n");
//prnIt(advIt2, prnInt);
//printf("> In 'it1', ");
//prnPrev(it1, prnInt);
freeIt(it1);
//freeIt(advIt1);
//freeIt(advIt2);
printf("--==== End of Test-03 ====------\n");
}
int main(int argc, char *argv[])
{
test1();
test2();
test3();
return EXIT_SUCCESS;
}
I'm trying to build an arraylist in C with the following code
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
// Declaration of ArrayList structure
typedef struct ArrayList {
int length, capacity;
int *items;
} ArrayList;
// Create a new ArrayList
ArrayList *newList() {
int *items = malloc(4 * sizeof(int));
ArrayList *list = malloc(sizeof(ArrayList));
list->length = 0;
list->capacity = 4;
list->items = items;
return list;
}
// Check and expand list if neccessary
void check(ArrayList *list) {
printf("Check called (%d, %d)\n", list->length, list->capacity);
if (list->length >= list->capacity) {
printf("Expanding\n");
list->capacity = list->capacity * 2;
printf("Reallocating\n");
list->items = realloc(list->items, list->capacity);
if (list->items == NULL) {
printf("realloc failed\n");
exit(1);
}
}
}
// Add a value to the ArrayList
void add(ArrayList *list, int n) {
check(list);
list->items[list->length] = n;
list->length++;
}
// Print the list
void printList(ArrayList *list) {
for (int i=0; i<list->length; i++) {
if (i > 0) printf(", ");
printf("%d", list->items[i]);
}
printf("\n");
}
int main () {
ArrayList *list = newList();
for (int i = 0; i < 20; i++) {
add(list, i);
}
printList(list);
}
When the array is full, the check function is called as it should be. However, the second time the check function is called, the program failes on the call to realloc giving the following error:
*** Error in `./test': realloc(): invalid next size: 0x0000000001d3c010 ***
Aborted (core dumped)
where the size varies every time the program is run.
I have read that this error is caused by a corrupt heap, which is normally caused by pointers going wrong somewhere. However, I cannot see where the problem lies in this example. Any help would be appreciated.
you are reallocating the list->items. realloc() function has 2 parameter
first one is void pointer ,this point to the memory block that previously allocated,and second parameter works for how many bytes have to reallocate.
in your code you added only the capacity...bt it is not .u have to add size of the int with capacity ...cause it only takes (size ) int byte ...
then it works fine
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
// Declaration of ArrayList structure
typedef struct ArrayList {
int length, capacity;
int *items;
} ArrayList;
int i;
// Create a new ArrayList
ArrayList *newList() {
int *items = malloc(4 * sizeof(int));
ArrayList *list = malloc(sizeof(ArrayList));
list->length = 0;
list->capacity = 4;
list->items = items;
return list;
}
// Check and expand list if neccessary
void check(ArrayList *list) {
printf("Check called (%d, %d)\n", list->length, list->capacity);
if (list->length >= list->capacity) {
printf("Expanding\n");
list->capacity = list->capacity * 2;
printf("Reallocating\n");
list->items = realloc(list->items, list->capacity * sizeof(int));
if (list->items == NULL) {
printf("realloc failed\n");
exit(1);
}
}
}
// Add a value to the ArrayList
void add(ArrayList *list, int n) {
check(list);
list->items[list->length] = n;
list->length++;
}
// Print the list
void printList(ArrayList *list) {
for (i=0; i<list->length; i++) {
if (i > 0) printf(", ");
printf("%d", list->items[i]);
}
printf("\n");
}
int main () {
ArrayList *list = newList();
for ( i = 0; i < 20; i++) {
add(list, i);
}
printList(list);
}
I want to read all pInd out of my rbtree neighbourList and store them in an array. The int pInd is simply the index for another array where I want to change values according to the stored adresses in my rbtree.
I have a array of structs (Pixel) and rbtree within each pixel holding the adress of neigbours.
//File rbtree.h
typedef struct rbtree_node_t {
int rInd;
int pInd;
struct rbtree_node_t* left;
struct rbtree_node_t* right;
struct rbtree_node_t* parent;
enum rbtree_node_color color;
} *rbtree_node;
typedef struct rbtree_t {
rbtree_node root;
} *rbtree;
//File rbtree.c
rbtree rbtree_create() {
rbtree t = malloc(sizeof(struct rbtree_t));
t->root = NULL;
verify_properties(t);
return t;
}
//----------------------------------------
//File main.c
typedef struct _Pixel
{
int mean;
rbtree neighbourList;
int index;
}Pixel;
void init(Pixel* p)
{
...
r[index].neighbourList = rbtree_create();
...
}
//----------------------------------------
void changepixel(Pixel* p,int index)
{
int *arr=NULL;
int i;
int size;
rbtree npl = r[index].neigbourList;
size = count(npl);
arr = calloc(size, sizeof(int));
AddNodeToArray(npl, arr, 0);
for (i=0; i<size; i++)
{
printf("arr[%d]: %d\n", i, arr[i]);
}
}
int AddNodeToArray(rbtree node, int arr[],int i);
{
if(node == NULL)
return i;
arr[i] = node->pInd;
i++;
if(node->left != NULL)
i = AddNodeToArray(node->left, arr, i);
if(node->right != NULL)
i = AddNodeToArray(node->right, arr, i);
return i;
}
int count(rbtree* node)
{
int c = 1;
if (node == NULL)
return 0;
else
{
c += count(node->left);
c += count(node->right);
return c;
}
}
//------------------------------
Pixel *p;
p = malloc((nx*ny)*sizeof(struct _Pixel));
Pixel p = r[10];
print_tree(p.npList);
changepixel(p,p.label);
Could someone explain me why printing the tree with
void print_tree_helper(rbtree_node n, int indent);
void print_tree(rbtree t) {
print_tree_helper(t->root, 0);
puts("");
}
void print_tree_helper(rbtree_node n, int indent) {
int i;
if (n == NULL) {
fputs("<empty tree>", stdout);
return;
}
if (n->right != NULL) {
print_tree_helper(n->right, indent + INDENT_STEP);
}
for(i=0; i<indent; i++)
fputs(" ", stdout);
if (n->color == BLACK)
printf("%d(%d)_bl\n", (int)n->rInd,(int)n->pInd);
else
printf("<%d>(%d)_re\n", (int)n->rInd,(int)n->pInd);
if (n->left != NULL) {
print_tree_helper(n->left, indent + INDENT_STEP);
}
}
works whereas my change doesen't? Or how to make it working using all the adresses found in a three for further working with these values?
GCC gives the error:
in function 'count' and in function 'AddNodeToArray'
request for member 'left' in something not a structure or union
Thank you in advance.
There are too many mistakes in your code. But for count and AddNodeToArray the main problem is that you confused with rbtree_node and rbtree types. rbtree_node is the struct with data you need, but rbtree is the struct with only one member - pointer to the root of the tree of type rbtree_node.
I could not test your code to point all of the errors, at least because it's not complete. However I guess to correct it you could try this.
count should be
int count_helper(rbtree_node node) {
int c = 1;
if (node == NULL)
return 0;
else {
c += count_helper(node->left);
c += count_helper(node->right);
return c;
}
}
int count(rbtree tree) {
if (tree == NULL)
return 0;
else {
return count_helper(tree->root);
}
}
and AddNodeToArray something like this
int AddNodeToArray_helper(rbtree_node tree, int arr[], int i) {
if(node == NULL)
return i;
arr[i] = node->pInd;
i++;
if(node->left != NULL)
i = AddNodeToArray_helper(node->left, arr, i);
if(node->right != NULL)
i = AddNodeToArray_helper(node->right, arr, i);
return i;
}
int AddNodeToArray_helper(rbtree tree, int arr[], int i) {
return AddNodeToArray_helper(tree->root, arr, i);
}
Okay so i have this Queue implementation that works, but i'm having some memory leak that doesn't let a if else operations runs after that.
File queue_arr.h
#define MaxQ 100
typedef struct {
int array[MaxQ];
int front;
int back;
int size;
}*Queue;
Queue init();
int enqueue(Queue q, int v);
int dequeue(Queue q, int *v);
int front(Queue q, int *v);
int isEmpty(Queue q);
File queue_arr.c
#include "queue_arr.h"
#include <stdlib.h>
#include <stdio.h>
Queue init() {
Queue q = (Queue)malloc(sizeof(Queue));
q->front = 0;
q->back = 0;
q->size = 0;
return q;
}
int enqueue(Queue q, int v) {
if(q->size==MaxQ)
return 0;
q->array[q->back] = v;
q->back++;
if(q->back == MaxQ)
q->back = 0;
q->size++;
return 1;
}
int dequeue(Queue q, int *v) {
if(q->size == 0)
return 0;
*v = q->array[q->front];
q->front++;
if(q->front == MaxQ)
q->front =0;
q->size--;
return 1;
}
int front(Queue q, int *v) {
if(q->size==0)
return 0;
*v = q->array[q->front];
return 1;
}
int isEmpty(Queue q) {
if(q->size == 0)
return 1;
return 0;
}
int main(){
Queue teste = init();
int *aux;
*aux = -1;
printf("Value : %d\n",*aux );
enqueue(teste,5);
enqueue(teste,10);
enqueue(teste,15);
front(teste,aux);
printf("Next costumer: %d\n",*aux );
dequeue(teste,aux);
printf("Costumer %d left queue\n",*aux );
dequeue(teste,aux);
printf("Costumer %d left queue\n",*aux );
dequeue(teste,aux);
printf("Costume %d left queue\n",*aux );
int random = 10;
if(random == 10)
printf("asdasdasd\n");
}
The last if and else statement doest not work, i noticed cause i was trying to do a isEmpty if clause, and keep leading me to segmentation fault.
Without the last three lines, the code compiles and runs, with no errors. But with that i just keep getting a segmentation fault.
Does anybody knows the problem ?
Your code can't decide whether a Queue is a pointer to something or the something.
typedef struct {
int array[MaxQ];
int front;
int back;
int size;
}*Queue;
This says a Queue is a pointer to a bunch of things.
Queue q = (Queue)malloc(sizeof(Queue));
q->front = 0;
This allocates enough bytes to hold a Queue, which is just a pointer, and then attempts to use the thing it points to. But you never allocated space for anything but a pointer.
Queue q = (Queue)malloc(sizeof(Queue));
Congratulations, sizeof(Queue) is 4 (or 8) bytes since it's a pointer.
Your segmentaion fault because of this
int *aux;
*aux = -1;
you should
aux = malloc(sizeof(int));
before
*aux = -1;
but I don't think that is what you want, instead you should just do it
int aux = -1;
and when calling dequeue
dequeue(teste, &aux);
Also I would recomend you fix these other issues
You don't need to cast malloc
You should check that malloc didn't return NULL otherwise you will dereference a
NULL pointer which is undefined behavior.
Also, your malloc call is passing the wrong size. A possible fix is to use
Queue q = malloc(sizeof(*q));
But I would actually recommend to avoid hiding the fact that variables are pointers completely.
You do have a memory leak but that is not a cause for a segmentaion fault, you should just call free(teste) at the end of main().
Your main() doesn't return you should, also add return 0; at the end of main() after free()
I fixed your code, hope this helps
#include <stdlib.h>
#include <stdio.h>
#define MaxQ 100
typedef {
int array[MaxQ];
int front;
int back;
int size;
} *Queue;
Queue init() {
Queue q = malloc(sizeof(*q));
if (q == NULL)
return NULL;
q->front = 0;
q->back = 0;
q->size = 0;
return q;
}
int enqueue(Queue q, int v) {
if (q == NULL)
return 0;
if(q->size==MaxQ)
return 0;
q->array[q->back] = v;
q->back++;
if(q->back == MaxQ)
q->back = 0;
q->size++;
return 1;
}
int dequeue(Queue q, int *v) {
if (q == NULL)
return 0;
if(q->size == 0)
return 0;
*v = q->array[q->front];
q->front++;
if(q->front == MaxQ)
q->front =0;
q->size--;
return 1;
}
int front(Queue q, int *v) {
if (q == NULL)
return 0;
if(q->size==0)
return 0;
*v = q->array[q->front];
return 1;
}
int isEmpty(Queue q) {
if (q == NULL)
return 0;
if(q->size == 0)
return 1;
return 0;
}
int main(){
Queue teste = init();
if (teste == NULL)
return -1;
int aux;
aux = -1;
printf("Value : %d\n", aux);
enqueue(teste,5);
enqueue(teste,10);
enqueue(teste,15);
front(teste, &aux);
printf("Next costumer: %d\n", aux );
dequeue(teste, &aux);
printf("Costumer %d left queue\n", aux );
dequeue(teste, &aux);
printf("Costumer %d left queue\n", aux );
dequeue(teste, &aux);
printf("Costume %d left queue\n", aux );
int random = 10;
if(random == 10)
printf("asdasdasd\n");
free(teste);
return 0;
}
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