making custom Malloc, what is wrong here? - c

I've been working on a little custom worstfit Malloc using a double-linked list for a while, and although this is small I thought this would work. Is there anything obvious that is wrong with this code?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "mymal.h"
typedef struct Node
{
int size;
int status;
struct Node *next;
struct Node *previous;
} Node;
Node *endNode;
Node *rootNode;
void *worstfit_mall(int size)
{
Node *theNode = sbrk (size + sizeof(theNode));
void *ptr;
if (rootNode == NULL)
{
theNode->status = 1;
theNode->size = size;
theNode->previous = theNode;
theNode->next = theNode;
rootNode = theNode;
endNode = theNode;
return theNode;
}
Node *worstNode;
worstNode = worstFit(size);
if (worstNode != NULL)
{
theNode->status = 1;
theNode->size = size;
Node *newNode = sbrk((worstNode->size - theNode->size) + sizeof(theNode));
newNode->status = 0;
newNode->size = worstNode->size - theNode->size;
theNode->next = newNode;
theNode->previous = worstNode->previous;
newNode->next = worstNode->next;
return newNode;
}
endNode->next = theNode;
endNode = theNode;
endNode->status = 1;
endNode->size = size;
ptr = sbrk(size + sizeof(theNode));
return ptr;
}
void my_free(void *ptr)
{
Node *pointer;
pointer = (Node*)ptr;
pointer->status = 0;
if ((pointer->next->status == 0) && (pointer->previous->status == 0))
sbrk(-1 * (pointer->next->size + pointer->size));
else if ((pointer->next->status == 1) && (pointer->previous->status == 0))
sbrk(-1 * (pointer->previous->size + pointer->size));
else if ((pointer->next->status == 0) && ( pointer->next->status == 0))
sbrk(-1 * (pointer->previous->size + pointer->next->size + pointer->size));
else
sbrk(-1 * pointer->size);
}
void *worstFit(int size)
{
Node *theNode = rootNode;
Node *worstNode;
while (theNode != NULL)
{
if ((worstNode == NULL || theNode->size > worstNode->size) && (theNode->size >= size) && (theNode->status == 0))
worstNode = theNode;
theNode = theNode->next;
}
return worstNode;
}

Here are the things that immediately strike me:
worstFit does not initialize worstNode to NULL and tries to read it while it's still garbage.
You create a linked list of Nodes, but the tail Node's next always points to itself. Meanwhile worstFit expects a NULL sentinel value when it iterates over the list.
worstfit_mall does not initialize endNode when initially creating rootNode.
worstfit_mall returns a pointer to the allocated Node, but if it's meant to be substitutable for malloc, it should be returning a pointer to memory that the caller is allowed to write to. You don't want the caller to scribble all over your Node data.
I'd expect worstfit_mall to return ((char*) node) + sizeof *node) (or more simply, node + 1) instead of returning node directly. my_free would need to do a corresponding, inverse adjustment to retrieve the Node pointer.
void my_free(void *ptr)
{
Node *nodePtr = ptr;
nodePtr--;
...
}
Additionally, it's unclear to me why worstfit_mall allocates memory via sbrk when going down the worstNode != NULL path. Isn't the point of this path to find an existing memory chunk to reuse? Furthermore, this path calls sbrk twice.
Finally, it appears to me that my_free unconditionally reduces the amount of allocated memory, but that would work only if you're freeing the last thing you allocated with sbrk. What if you called worstfit_mall twice and then called my_free on the first result? There is no path where my_free marks the memory chunk as no-longer-in-use so that worstfit_mall can reuse it later.
I don't know if there are other problems with your code; I would say that there very likely are given these types of fundamental issues.

Related

My code for pre-order traversal of Binary Search Tree is working but how is the stack whose each element is a pointer to the structure working?

This is my code of preorder traversal of BST. It's working fine on Ubuntu. But I don't understand one thing.
In the function iterative_preorder(), I actually wanted a stack to store the pointers to the structure that I defined on the top. I want to know the concept that how is it working. Since, while allocating memory to the stack, I didn't specify anywhere separately that stack should contain size number of pointers to the structure.
Like, when we define:
int stack[size];
We know that stack[1] will be the second block in the stack. But here, I used malloc, which actually just makes one block of the size specified as size * sizeof(node *).
So when the program executes:
stack[++top] = root;
How does the program understand that it has to go to the next pointer to the structure in the stack? I hope my question is clear.
I made another small program, based on the confusion that I had. Here, instead of structure, I used int. I tried to create a stack of size 2, which stores pointers to the integer. Here's the code:
#include <stdio.h>
#include <stdlib.h>
void main() {
int** stack = (int**)malloc(2 * sizeof(int*));
printf("%d", *stack[0]);
}
But this code is throwing segmentation fault (core dumped). As both the codes used the same logic, just that this one used int instead of structure, I don't understand why this is throwing error.
#include <stdio.h>
#include <stdlib.h>
int size = 0;
typedef struct mylist {
int data;
struct mylist *left;
struct mylist *right;
} node;
node *root;
void create_root(node *root) {
root = NULL;
}
//Inserting nodes
node *insert(node *root, int val) {
node *ptr, *parentptr, *nodeptr;
ptr = (node*)malloc(sizeof(node));
ptr->data = val;
ptr->left = NULL;
ptr->right = NULL;
if (root == NULL)
root = ptr;
else {
parentptr = NULL;
nodeptr = root;
while (nodeptr != NULL) {
parentptr = nodeptr;
if (val < nodeptr->data)
nodeptr = nodeptr->left;
else
nodeptr = nodeptr->right;
}
if (val < parentptr->data)
parentptr->left = ptr;
else
parentptr->right = ptr;
}
return root;
}
void iterative_preorder(node *root) {
if (root != NULL) {
int top = -1;
node **stack = (node**)malloc(size * sizeof(node*));
node *cur;
stack[++top] = root;
while (top > -1) {
cur = stack[top--];
printf("%d\t", cur->data);
if (cur->right != NULL)
stack[++top] = cur->right;
if (cur->left != NULL)
stack[++top] = cur->left;
}
}
}
void main() {
int option, val;
node *ptr;
int flag = 1;
create_root(root);
while (flag != 2) {
printf("\nChoose-\n1-Insert\n2-Iterative Preorder Traversal\n3-Exit\n");
scanf("%d", &option);
switch (option) {
case 1: {
printf("\nEnter the value of new node\n");
size++;
scanf("%d", &val);
root = insert(root, val);
}
break;
case 2:
iterative_preorder(root);
break;
case 3:
flag = 2;
break;
default:
printf("\nWrong entry\n");
}
}
}
Your code has a dereference of uninitialized pointer error.
int** stack = (int**)malloc(2*sizeof(int*));
printf("%d",*stack[0]);
In the above code, stack points to an array of two int pointers, what stack[0] points to? it's not initialized.
A live test of your code is available here segfault. you can modify and test it again.

custom malloc function for c

I try to write my own custom malloc and free function in c. I worked around 12 hours on this and tried lots of things. But it doesn't work.
Maybe you guys can figure out the error. Allocated memory gets removed from the list with a next pointer to a specific address to identify it later in the free function. The current error is a segmentation fault 11 in the split method.
C-File:
Head:
#define MAGIC ((void*)0xbaadf00d)
#define SIZE (1024*1024*1)
typedef struct mblock {
struct mblock *next;
size_t size;
char memory[];
}mblock;
char memory[SIZE];
static struct mblock *head;
malloc:
void *halde_malloc (size_t size) {
printf("Starting\n");
printf("%zu\n",size);
if(size <= 0) {return NULL;}
if(head == NULL){
initializeBlock();
printf("Memory initialized\n");
}
mblock *temp_block = head;
while(temp_block != NULL) {
printf("IN\n");
if(temp_block->size == size) {
list_remove(temp_block);
temp_block->next = MAGIC;
return (void*)(temp_block);
} else if(temp_block->size > size) {
size_t temp_size = temp_block->size;
printf("size IS more than equal\n");
list_split_AND_Remove(temp_size - size, temp_block);
temp_block->size = size;
temp_block->next = MAGIC;
return (void*)(temp_block);
}
temp_block = temp_block->next;
printf("One block checked\n");
}
errno = ENOMEM;
return NULL;
}
Initialize:
void initializeBlock(){
printf("Initializing\n");
head = (mblock*)memory;
head->size=sizeof(memory)-sizeof(mblock);
head->next=NULL;
}
Split:
void list_split_AND_Remove(size_t size, mblock *lastBlock) {
printf("Split\n");
mblock *new = (void*)((mblock*)lastBlock+size+sizeof(mblock));
new->size = size - sizeof(mblock);
new->next = lastBlock->next;
lastBlock->next = new;
printf("START REMOVE");
list_remove(lastBlock);
}
Remove:
void list_remove(mblock *p) {
printf("Remove\n");
mblock *temp_block = head;
if(p == head) {
if(head->next == NULL) {
head = NULL;
return;
} else {
head = p->next;
return;
}
}
while(temp_block->next != NULL) {
if(temp_block->next == p) {
printf("Found P:");
temp_block = p->next;
return;
}
temp_block = temp_block->next;
}
}
Free:
void halde_free (void *ptr) {
printf("FREE\n");
mblock *new_block = ptr;
if(new_block->next == MAGIC) {
new_block->next = head;
head = new_block;
} else {abort();}
}
Issues with your code include, but are not necessarily limited to:
list_remove() does not actually remove the specified block from the list unless it happens to be the current list head. In every other case, therefore, halde_malloc() corrupts the list after calling list_remove() when it modifies the node's next pointer.
list_split_AND_Remove() performs incorrect pointer arithmetic. Specifically, mblock *new = (void*)((mblock*)lastBlock+size+sizeof(mblock)); does not do what you appear to want to do, because pointer arithmetic operates in units the size of the pointed-to type, whereas the size argument and the result of the sizeof operator have units of individual bytes. (Also, both casts are useless, albeit not harmful in themselves.)
Your allocator returns a pointer to the block header, not to its data. As a result, the user will very likely overwrite the block header's contents, leading to havoc when you later try to free that block.
You seem to assume that mblock objects have an alignment requirement of 1. That might not be true.

Needing advice for implementing malloc and free in C

For school, I need to write a program that uses my own implementation of malloc and free. I need to be able to report on all the chunks of memory in my 'heap', whether it's allocated or not. I feel like I've written good code to do so, but evidently not. The first few times I ran it, the report kept reporting on the same address forever. While trying to debug that, there came a point that the program wouldn't even let me start allocate space to use as my 'heap', it would just get a segmentation fault and quit. Any pointers on where I'm going wrong, or even to clean up my code at all, would be super helpful.
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#define WORDSIZE 8
#define ALLOCMAGIC 0xbaddecaf
#define FREEMAGIC 0xdeadbeef
typedef struct __header_t {
size_t size;
int magic;
} header_t;
typedef struct __node_t {
size_t size;
struct __node_t *next;
} node_t;
node_t *head = NULL;
// Find the free node that occurs just before the given node.
node_t *findLastFree(node_t * node) {
// Initialize some pointers to traverse the free node linked list;
node_t *lastFree = head;
node_t *nextFree = lastFree->next;
// Traverse linked list until the last node's pointer is pointed to NULL,
// meaning the end of the list.
while (nextFree != NULL) {
// Check if target node is less than the next node, meaning the target node
// is between last and next. If so, then return last node.
if (node < nextFree) {
return lastFree;
}
lastFree = nextFree;
nextFree = lastFree->next;
}
// If we have reached the end of the list and the target node is still greater
// than the last node, return last node.
return lastFree;
}
// If the given pointer is allocated, deallocate the space and coalesce the free
// node list.
void myFree(void *ptr) {
// Initialize some free node pointers and assert that the given pointer is
// the beginning of allocated space.
node_t *lastFree;
node_t *nextFree;
node_t *newFree;
header_t *block = ((header_t *) ptr) - 1;
assert(block->magic == ALLOCMAGIC);
// Set this block's signal to free space
block->magic = FREEMAGIC;
// Typecast the block into a free node and set it's size.
size_t size = block->size + sizeof(header_t);
newFree = (node_t *) block;
newFree->size = size;
// Check if node is before the first free node. If so set the new node as
// the new head. If not, then handle node as it occurs after head.
if (newFree < head) {
nextFree = head;
// Check if new node ends at the start of head. If so, merge them
// into a single free node. Else point the new node at the previous head.
// Either way, set new free as the new head.
if ((newFree + newFree->size) == head) {
newFree->next = head->next;
newFree->size = newFree->size + head->size;
} else {
newFree->next = head;
}
head = newFree;
} else {
// Set the free nodes for before and after the new free node.
lastFree = findLastFree(newFree);
nextFree = lastFree->next;
// Check if new node is the last node. If so, point the previous final
// node at the new node and point the new node at NULL.
if (nextFree == NULL) {
lastFree->next = newFree;
newFree->next = NULL;
}
// Check if end of new node is touching next node. If so, merge them
// into a single free node. Else point new free and next free.
if ((newFree + newFree->size) == nextFree) {
newFree->next = nextFree->next;
newFree->size = newFree->size + nextFree->size;
} else {
newFree->next = nextFree;
}
// Check if start of new node is touching last free node. If so, merge
// them into a single free node. Else point last's next to new free.
if ((lastFree + lastFree->size) == newFree) {
lastFree->next = newFree->next;
lastFree->size = lastFree->size + newFree->size;
} else {
lastFree->next = newFree;
}
}
}
// Split the given free node to fit the given size. Create a new node at the
// remainder and rearrange the free list to accomodate.
void splitBlock(node_t *node, size_t size) {
// Create a new pointer at the end of the requested space.
void *newBlock = node + size;
// Set the bits of the new space as if it were allocated then freed.
header_t *hptr = (header_t *) newBlock;
hptr->size = (node->size - size - sizeof(header_t));
hptr->magic = FREEMAGIC;
// Typecast the new space into a node pointer. Reinsert it into the free
// node list.
node_t *newFree = (node_t *) newBlock;
newFree->size = node->size - size;
newFree->next = node->next;
node_t *lastFree = findLastFree(newFree);
lastFree->next = newFree;
}
// Find a free node that can fit the given size. Split the node so no space is
// wasted. If no node can fit requested size, increase the heap size to accomodate.
void *findFirstFit(size_t size) {
// Create a node pointer to traverse the free node list.
node_t *node = head;
// Traverse the list until the end is reached.
while(node != NULL) {
// Check if the node can accomodate the requested size.
if (node->size >= size) {
// Split the current node at the requested size and return a pointer
// to the start of the requested space.
splitBlock(node, size);
return (void *) node;
}
node = node->next;
}
// No free space could fit requested size, so request more space at the end
// of the heap.
void *newspace = sbrk(size);
assert(newspace >= 0);
return newspace;
}
// Allocate a block of space for the given size and return a pointer to the start
// of the freed space.
void *myMalloc(size_t need) {
// Round the given size up to the next word size. Add the size of a header to
// the amount actually needed to allocate.
need = (need + WORDSIZE - 1) & ~(WORDSIZE - 1);
size_t actual = need + sizeof(header_t);
// Find a free node that can accomodate the given size. Check it is valid.
void *firstfit = findFirstFit(actual);
assert(firstfit >= 0);
// Create a header for the newly allocated space.
header_t *hptr = (header_t *) firstfit;
hptr->magic = ALLOCMAGIC;
hptr->size = need;
return (void *) (hptr + 1);
}
// Print a report on the space starting at the given pointer. Return a pointer to
// the start of the next block of space.
void *reportAndGetNext(void *ptr) {
void *nextptr;
header_t *hptr = (header_t *) ptr;
// Check if the pointer is pointing to allocated space.
if (hptr->magic == ALLOCMAGIC) {
// Report the characteristics of the current block.
printf("%p is ALLOCATED starting at %p and is %zd bytes long.\n", hptr, (hptr + 1), hptr->size);
// Set the next pointer to be returned.
nextptr = hptr + hptr->size + sizeof(header_t);
} else {
// Cast the pointer as a free node. Set the next pointer to be returned.
node_t *free = (node_t *) ptr;
nextptr = free + free->size;
// Report the characteristics of the current block.
printf("%p is FREE for %zd bytes.\n", hptr, free->size);
}
return nextptr;
}
// Report on all blocks of space contained within the heap space, starting at the
// given pointer.
void report(void* startheap) {
void *ptr = startheap;
void *end = sbrk(0);
int count = 50;
printf("Current Status of Heap:\n");
while (ptr != NULL && count > 0) {
ptr = reportAndGetNext(ptr);
count = count - 1;
}
printf("Heap Length: %zd \n", (end - startheap));
}
int main(void) {
void *start = sbrk(4096);
assert(start >= 0);
head = (node_t *) start;
head->size = 4096;
head->next = NULL;
printf("Allocating block 1");
void *ptr1 = myMalloc(26);
void *ptr2 = myMalloc(126);
report(start);
myFree(ptr1);
myFree(ptr2);
return 0;
}
The first obvious error I see is with pointer arithmentic. SplitBlock is trying to split size bytes from the front of a block, but when you do:
void splitBlock(node_t *node, size_t size) {
// Create a new pointer at the end of the requested space.
void *newBlock = node + size;
Your newBlock pointer is actually size * sizof(node_t) bytes into the block -- which may well be past the end of the block. You need to cast node to a char * before doing pointer arithmetic with it if you want byte offsets. However, you may then run into alignment issues...

How to free memory occupied by a Tree, C?

I'm currently dealing with a generic Tree with this structure:
typedef struct NODE {
//node's keys
unsigned short *transboard;
int depth;
unsigned int i;
unsigned int j;
int player;
int value;
struct NODE *leftchild; //points to the first child from the left
struct NODE *rightbrothers; //linked list of brothers from the current node
}NODE;
static NODE *GameTree = NULL;
While the function that allocates the different nodes is (don't bother too much at the keys' values, basically allocates the children-nodes. If there aren't any the new child goes to leftchild, otherwise it goes at the end of the list "node->leftchild->rightbrothers"):
static int AllocateChildren(NODE **T, int depth, unsigned int i, unsigned int j, int player, unsigned short *transboard) {
NODE *tmp = NULL;
if ((*T)->leftchild == NULL) {
if( (tmp = (NODE*)malloc(sizeof(NODE)) )== NULL) return 0;
else {
tmp->i = i;
tmp->j = j;
tmp->depth = depth;
(player == MAX ) ? (tmp->value = 2 ): (tmp->value = -2);
tmp->player = player;
tmp->transboard = transboard;
tmp->leftchild = NULL;
tmp->rightbrothers = NULL;
(*T)->leftchild = tmp;
}
}
else {
NODE *scorri = (*T)->leftchild;
while (scorri->rightbrothers != NULL)
scorri = scorri->rightbrothers;
if( ( tmp = (NODE*)malloc(sizeof(NODE)) )== NULL) return 0;
else {
tmp->i = i;
tmp->j = j;
tmp->depth = depth;
(player == MAX) ? (tmp->value = 2) : (tmp->value = -2);
tmp->player = player;
tmp->transboard = transboard;
tmp->leftchild = NULL;
tmp->rightbrothers = NULL;
}
scorri->rightbrothers = tmp;
}
return 1;
}
I need to come up with a function, possibly recursive, that deallocates the whole tree, so far I've come up with this:
void DeleteTree(NODE **T) {
if((*T) != NULL) {
NODE *tmp;
for(tmp = (*T)->children; tmp->brother != NULL; tmp = tmp->brother) {
DeleteTree(&tmp);
}
free(*T);
}
}
But it doesn't seem working, it doesn't even deallocate a single node of memory.
Any ideas of where I am being wrong or how can it be implemented?
P.s. I've gotten the idea of the recursive function from this pseudocode from my teacher. However I'm not sure I've translated it correctly in C with my kind of Tree.
Pseudocode:
1: function DeleteTree(T)
2: if T != NULL then
3: for c ∈ Children(T) do
4: DeleteTree(c)
5: end for
6: Delete(T)
7: end if
8: end function
One thing I like doing if I'm allocating lots of tree nodes, that are going to go away at the same time, is to allocate them in 'batches'. I malloc then as an array of nodes and dole them out from a special nodealloc function after saving a pointer to the array (in a function like below). To drop the tree I just make sure I'm not keeping any references and then call the free routine (also like below).
This can also reduce the amount of RAM you allocate if you're lucky (or very smart) with your initial malloc or can trust realloc not to move the block when you shrink it.
struct freecell { struct freecell * next; void * memp; } * saved_pointers = 0;
static void
save_ptr_for_free(void * memp)
{
struct freecell * n = malloc(sizeof*n);
if (!n) {perror("malloc"); return; }
n->next = saved_pointers;
n->memp = memp;
saved_pointers = n;
}
static void
free_saved_memory(void)
{
while(saved_pointers) {
struct freecell * n = saved_pointers;
saved_pointers = saved_pointers->next;
free(n->memp);
free(n);
}
}
I've just realized my BIG mistake in the code and I'll just answer myself since no one had found the answer.
The error lies in this piece of code:
for(tmp = (*T)->children; tmp->brother != NULL; tmp = tmp->brother) {
DeleteTree(&tmp);
}
First of all Ami Tavory was right about the for condition, i need to continue as long as tmp != NULL
Basically it won't just work because after the DeleteTree(&tmp), I can no longer access the memory in tmp because it's obviously deleted, so after the first cycle of for ends I can't do tmp = tmp->rightbrother to move on the next node to delete because tmp->rightbrother no longer exists as I just deleted it.
In order to fix it I just needed to save the tmp->brother somewhere else:
void DeleteTree(NODE **T) {
if((*T) != NULL) {
NODE *tmp, *deletenode, *nextbrother;
for(tmp = (*T)->children; tmp != NULL; tmp = nextbrother) {
nextbrother = tmp->rightbrother;
DeleteTree(&tmp);
}
canc = (*T);
free(*T);
(*T) = NULL;
}
}
Just for the sake of completeness I want to add my version of DeleteTree
void DeleteTree(NODE *T) {
if(T != NULL) {
DeleteTree(T->rightbrothers);
DeleteTree(T->leftchild);
free(T);
}
}
I think it is much less obscure and much easier to read. Basically it solves the issue in DeleteTree but through eliminating the loop.
Since we free the nodes recursively we might as well do the whole process recursively.

pointers N linked list in C

I wrote to following code which does not work. The application crashes on the print method.
Any idea where it goes wrong?
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int item;
struct LinkedList *Next;
} LinkedList;
int main()
{
LinkedList vaz;
vaz.item = 14123;
vaz.Next = 0;
add(&vaz,123);
add(&vaz,9223);
Print(&vaz);
return 0;
}
void Print(LinkedList* Val)
{
if(Val != 0){
printf("%i\n",(*Val).item);
Print((*Val).Next);
}
}
void add(LinkedList *Head, int value)
{
if((*Head).Next == 0 )
{
LinkedList sab;
sab.item = value;
sab.Next = 0;
(*Head).Next = &sab;
}
else{
add((*Head).Next,value);
}
}
Your add method should allocate memory dynamically, you are using automatic allocation (local variables), which is freed when you 'leave' the function. This will cause an undefined behavior when you try to access this memory later on.
void add(LinkedList *Head, int value)
{
if((*Head).Next == 0 )
{
LinkedList sab; <-- need to be allocated dynamically
sab.item = value;
sab.Next = 0;
(*Head).Next = &sab;
}
else{
add((*Head).Next,value);
}
}
You did not allocate heap memory to the Linked list you create. I think you should allocate memory on the heap when you add elements to the linked list. The linked list variable 'sab' is local to the method and so the memory get deallocated as soon as the function goes out of scope.
To add an element, you need to do as follows:
LinkedList *sab = (struct LinkedList*) malloc (sizeof(struct LinkedList));
if( sab != NULL )
{
sab->item = value;
sab->next = NULL;
}
For more details, you can refer: http://www.cprogramming.com/snippets/source-code/singly-linked-list-insert-remove-add-count
add should dynamically allocate memory as follows:
void add(LinkedList *Head, int value)
{
if (Head == NULL)
return;
if((*Head).Next == NULL )
{
LinkedList *sab = malloc(sizeof(LinkedList));
if ( sab == NULL ) {
// Error: ran out of memory (really shouldn't happen, but could)
return;
}
(*sab).item = value;
(*sab).Next = NULL;
(*Head).Next = sab;
}
else{
add((*Head).Next,value);
}
}
Also, the recursive call is "overkill" in this case. A simple loop would suffice:
void add(LinkedList *Head, int value)
{
if (Head == NULL)
return;
while ((*Head).Next != NULL)
Head = (*Head).Next;
LinkedList *sab = malloc(sizeof(LinkedList));
if ( sab == NULL ) {
// Error: ran out of memory (really shouldn't happen, but could)
return;
}
(*sab).item = value;
(*sab).Next = NULL;
(*Head).Next = sab;
}
I'd likewise avoid the recursive call for printing:
void Print(LinkedList* Val)
{
while (Val != NULL) {
printf("%i\n", (*Val).item);
Val = (*Val).Next;
}
}
If you have a function which removes items from the list, you need to ensure that you do a free on the pointer to that item that's removed.
Your LinkedList *Head doesn't have any memory First assign memory to it as given below-
LinkedList *Head = (struct LinkedList*)malloc(sizeof(struct LinkedList));

Resources