Creating Node Linear Linked List - c

I'm trying to create a linear linked list.
Seemed pretty simple but even though the code looks fine it won't compile.
Here's the header file and the main. Could you tell me what the problem is?
#include <malloc.h>
typedef int TYP;
typedef struct
{
TYP info;
node_linear_linked_list *next;
} node_linear_linked_list;
void init_linear_linked_list(node_linear_linked_list **manager)
{
*manager = NULL;
}
void push_linear_linked_list(node_linear_linked_list **manager, TYP info)
{
node_linear_linked_list *ptr =
(node_linear_linked_list *)malloc(sizeof(node_linear_linked_list));
ptr->info = info;
ptr->next = *manager;
*manager = ptr;
}
void insert_after_linear_linked_list(node_linear_linked_list *before, TYP info)
{
node_linear_linked_list *ptr =
(node_linear_linked_list *)malloc(sizeof(node_linear_linked_list));
ptr->info = info;
ptr->next = before->next;
before->next = ptr;
}
void pop_linear_linked_list(node_linear_linked_list **manager)
{
node_linear_linked_list *temp_ptr = *manager;
*manager = temp_ptr->next;
free(temp_ptr);
}
void delete_after_linear_linked_list(node_linear_linked_list *before)
{
node_linear_linked_list *temp_ptr = before;
before->next = before->next->next;
free(temp_ptr);
}
here's the main:
#include <malloc.h>
#include "node_linear_linked_list.h"
void main(void)
{
node_linear_linked_list *manager =
(node_linear_linked_list *)malloc(sizeof(node_linear_linked_list));
init_node_linear_linked_list(&manager);
getch();
}
Would appreciate some help. Thanks.

According to the C Standard
5 Tw o declarations of structure, union, or enumerated types which are in different scopes or use different tags declare distinct types. Each declaration of a structure, union, or enumerated type which does not include a tag declares a distinct type.
In this declaration
typedef struct
{
TYP info;
node_linear_linked_list *next;
} node_linear_linked_list;
there is declared an unnamed structure. In this data member declaration
node_linear_linked_list *next;
the name node_linear_linked_list is undefined.
You have to write for example
typedef struct node_linear_linked_list
{
TYP info;
struct node_linear_linked_list *next;
} node_linear_linked_list;
This function
void delete_after_linear_linked_list(node_linear_linked_list *before)
{
node_linear_linked_list *temp_ptr = before;
before->next = before->next->next;
free(temp_ptr);
}
has a bug. I think you mean
void delete_after_linear_linked_list(node_linear_linked_list *before)
{
if ( before && before->next )
{
node_linear_linked_list *temp_ptr = before->next;
before->next = before->next->next;
free(temp_ptr);
}
}
This statement in main
node_linear_linked_list *manager =
(node_linear_linked_list *)malloc(sizeof(node_linear_linked_list));
results in a memory leak because in the following statement
init_node_linear_linked_list(&manager);
the pointer is reassigned.
Also I advice to do a check in the functions whether a pointer passed as the argument is equal to NULL.

Related

Node deletion in linked list from beginning

I want to delete the first node and return the value of the deleted node. But I an getting this warning:
warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
example=(**example).next;
So, my code does not work. Can anyone help me to fix this? Thanks.
struct myStruct {
int data;
struct myStruct next;
}
int deleteNode(struct myStruct **example) {
struct myStruct *temporary;
if (temporary == NULL) {
emptyNode(temporary); // this function only returns NULL
}
temporary = *example;
example = (**example).next;
free(temporary);
return (**example).data;
}
This structure declaration contains at least two typos.
struct myStruct
{
int data;
struct myStruct next;
}
The first one is that there is no semicolon after the closing brace. And the second one is that the data member next must have pointer type.
It seems you mean
struct myStruct
{
int data;
struct myStruct *next;
};
As for the error message then in this assignment
example=(**example).next;
the left side hand operand has the type struct myStruct ** while the right hand side operand has the type struct myStruct * and these pointer types are not compatible. So the compiler issues an error.
Nevertheless the function in any case is invalid because you are using uninitialized variables like
struct myStruct *temporary;
if(temporary==NULL)
//...
The function interface is bad.because it is unclear what the function returns in case when it is called for an empty list.
The function can be declared and defined the following way.
int deleteNode( struct myStruct **example, int *data )
{
int success = *example != NULL;
if ( success )
{
struct myStruct *temporary = *example;
*example = ( *example )->next;
*data = temporary->data;
free( temporary );
}
return success;
}
And it can be called as it is shown below
#include <stdio.h>
#include <stdlib.h>
struct myStruct
{
int data;
struct myStruct *next;
};
int deleteNode( struct myStruct **example, int *data )
{
int success = *example != NULL;
if ( success )
{
struct myStruct *temporary = *example;
*example = ( *example )->next;
*data = temporary->data;
free( temporary );
}
return success;
}
int main(void)
{
struct myStruct *head = 0;
// fill the list
int data;
if ( deleteNode( &head, &data ) )
{
printf( "The deleted value is %d\n", data );
}
else
{
puts( "The list is empty." );
}
return 0;
}

Dereferencing pointer to incomplete type

I am new to C programming and as a mini project I decided to try to implement a stack in C using OOP style structure in a file GenericStack.h as shown below:
void _GENERICSTACK0001(void *,void *);
void *_GENERICSTACK0002(void *);
int _GENERICSTACK0003(void *);
typedef struct
{
struct GenericStackNode *next;
void *data;
int type;
}GenericStackNode;
typedef struct
{
struct GenericStackNode *top;
int count;
void (*add)(void *,void *);
void *(*pop)(void *);
int (*hasNext)(void *);
int (*getCount)(void *);
}GenericStack;
GenericStack newGenericStack()
{
GenericStack *genStack = malloc(sizeof(GenericStack));
genStack->add = _GENERICSTACK0001;
genStack->pop = _GENERICSTACK0002;
genStack->hasNext = _GENERICSTACK0003;
genStack->getCount = _GENERICSTACK0003;
genStack->top=NULL;
genStack->count = 0;
return *genStack;
}
void _GENERICSTACK0001(void *self,void *data)//add
{
GenericStack *genStack = self;
if(genStack->top == NULL)
{
genStack->top = malloc(sizeof(GenericStackNode));
genStack->top->next = NULL;
genStack->top->type = 0;
genStack->top->data = data;
}
else
{
GenericStackNode *temp = malloc(sizeof(GenericStackNode));
temp->next = genStack->top;
temp->type = 0;
temp->data = data;
genStack->top = temp;
genStack->count++;
}
}
void *_GENERICSTACK0002(void *self)//pop
{
GenericStack *genStack = self;
void *data = NULL;
if(genStack->top == NULL)
{
return data;
}
else
{
GenericStackNode *temp = genStack->top;
genStack->top = genStack->top->next;
data = temp->data;
free(temp);
genStack->count--;
return data;
}
}
int _GENERICSTACK0003(void *self)
{
GenericStack *genStack = self;
return genStack->count;
}
All I need to know is why (among many others) I get the specific error:
GenericStack.h:41:16: error: dereferencing pointer to incomplete type
genStack->top->type = 0;
I have checked the other answers on stackoverflow concerning "dereferencing pointer to incomplete type" but I cant seem to understand.
You're getting an error from GenericStack, but you have a problem in both GenericStack and GenericStackNode.
In C, struct X and X are different types. When you write:
struct GenericStackNode *next;
it declares a type called struct GenericStackNode (and a member which is a pointer to that type). This type is incomplete because you have not provided the struct definition.
The type could be completed by providing a struct definition later, but you never do that. Instead, you define an unnamed struct and typedef GenericStackNode to it , but that has no effect on struct GenericStackNode.
Then, struct GenericStackNode *top; still uses this same incomplete type, not the struct you defined above.
Assuming you meant for this pointer to be a pointer to the same type of struct it's contained in, you could use this pattern for both of your structs:
typedef struct X X;
struct X
{
X *ptr;
};
Often people combine the typedef with the struct definition but I find it clearer to have them separate.
You already type-defined GenericStackNode as a type, there is no need for struct GenericStackNode anymore, just GenericStackNode :
typedef struct
{
struct GenericStackNode *top;
...
}
should be only
typedef struct
{
GenericStackNode *top;
...
}
also , you can't use GenericStackNode when you still havn't defined it yet :
typedef struct
{
struct GenericStackNode *next;
void *data;
int type;
} GenericStackNode ;
you can write :
typedef struct GenericStackNode
{
struct GenericStackNode *next;
void *data;
int type;
} GenericStackNode ;

Undeclared identifiers with structs

struct FailedTransaction{
OrderNodePtr order;
int failureID;
struct FailedTransaction* next;
struct FailedTransaction* tail;
};
typedef struct FailedTransaction* FailedTransactionPtr;
struct SuccessfulTransaction{
OrderNodePtr order;
struct SuccessfulTransaction* next;
struct SuccessfulTransaction* tail;
};
typedef struct SuccessfulTransaction* SuccessfulTransactionPtr;
struct FinalReport{
FailedTransactionPtr failedTransactions;
SuccessfulTransactionPtr successfulTransactions;
};
struct FinalReport* report = NULL;
This code is declared above main. When accessing
report->successfulTransactions
or
report->failedTransactions
I get undefclared identifier for FailedTransaction and SuccessfulTransaction.
Here is the code that manipulates report
if(report == NULL){
report = malloc(sizeof(struct FinalReport));
report->failedTransactions = NULL;
report->successfulTransactions = NULL;
}
if(outcome){
if(report->successfulTransactions == NULL){
report->successfulTransactions = malloc(sizeof(SuccessfulTransaction));
report->successfulTransactions->order = temp;
report->successfulTransactions->tail = report->successfulTransactions;
}else{
report->successfulTransactions->tail->next = malloc(sizeof(SuccessfulTransaction));
report->successfulTransactions->tail->next->order = temp;
report->successfulTransactions->tail = report->successfulTransactions->tail->next;
}
}else{
if(report->failedTransactions == NULL){
report->failedTransactions = malloc(sizeof(FailedTransaction));
report->failedTransactions->order = temp;
report->failedTransactions->tail = report->failedTransactions;
}else{
report->failedTransactions->tail->next = malloc(sizeof(FailedTransaction));
report->failedTransactions->tail->next->order = temp;
report->failedTransactions->tail = report->failedTransactions->tail->next;
}
report->failedTransactions->failureID = outcome;
}
The errors occur at the first lines after each if statements and else statements.
This is for an assignment and I have been stuck on this for an hour or so (it is due tomorrow night). Can't figure out why it is happening and I can't find anything online. Any help would be appreciated.
This is the header file that contains OrderNodePtr
#ifndef _CONSUMER_
#define _CONSUMER_
struct OrderNode{
char title[250];
int id;
double cost;
char category[250];
struct OrderNode* next;
struct OrderNode* tail;
};
typedef struct OrderNode* OrderNodePtr;
#endif
Try
sizeof(struct FailedTransaction);
Or, make FailedTransaction a typedef:
struct _FailedTransaction;
typedef struct _FailedTransaction FailedTransaction;
struct _FailedTransaction {
OrderNodePtr order;
int failureID;
FailedTransaction* next;
FailedTransaction* tail;
};
Why does C need "struct" keyword and not C++?

Inserting an Element to a Linked List

I am working for a C exam and while trying to insert an element to a linked list, I am encountering with a runtime problem. My only purpose is adding 4 elements to list and then printing the list. However, it gives an error. I already looked some insertion codes and my code seems right. Can't see the error. Any assistance would be appreciated.
#include <stdio.h>
#include <stdlib.h>
struct ders{
char kod;
struct ders *next;
}*header;
typedef struct ders Ders;
void add(Ders*,Ders*);
void print(Ders*);
int main(void)
{
header = NULL;
Ders *node = NULL;
int i = 0;
char c;
while(i<4)
{
scanf("%c",&c);
node = (Ders*)malloc(sizeof(Ders));
node->kod = c;
node->next = NULL;
add(header,node );
i++;
}
print(header);
return 0;
}
void add(Ders *header, Ders *node)
{
if(header == NULL){
header = node;
header->next = NULL; }
else{
node->next = header;
header = node;
}
}
void print(Ders *header)
{
Ders *gecici = header;
while(gecici != NULL){
printf("%c\n",gecici->kod);
gecici = gecici->next;
}
}
As nihirus stated,
"The pointer is passed by value. Thus you can change the memory it points but you can't change the actual pointer, i.e. make it point to something else."
Your modification resulted in error *header is not member of struct
because
->
has a higher precedence than
*
Try using
(*header)->next = NULL
instead.
C operator precedence:
http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm

creating a queue of pointers in c

i have a dynamic number of pointers all having the same size. i need to store all the addresses of my pointers in some place like a link List in order to fetch them later on.
my question is what structs should i use. is the following correct:
struct Node{
int *k;
Node*Next;
}
struct LS{
Node*first,*last;
void push(Node*n);
Node* GetFirst();
Node* GetLast();
}
the LS is the linked list that stores Nodes. and a Node is a struct that holds the address of my pointer and a pointer to the next Node.
am i using int *k to store the address of my pointer correctly? should i continue with this implementation or is there any easier way to do this?
this sample code may help you start...
#include <stdio.h>
struct Node{
int *k;
Node *Next;
}* Temp;
struct LS
{
Node *first,*last;
void push(Node *MyNode)
{
MyNode->Next=NULL;
if(empty())
{
first=MyNode;
last=MyNode;
}
else
{
last->Next = MyNode;
last=MyNode;
}
}
Node* front()
{
return first;
}
void pop()
{
free(first->k);
first=first->Next;
}
bool empty()
{
if(first==NULL) return true;
return false;
}
};
int N=10;
int main()
{
LS Q;Q.first=NULL;
for(int i=0;i<3;i++)
{
Node *NewNode= (Node*)malloc(sizeof(Node));
NewNode->k = (int*)malloc(sizeof(int)*N);
for(int k=0;k<N;k++) NewNode->k[k]=i;
Q.push(NewNode);
}
while(!Q.empty())
{
Temp=Q.front();
for(int i=0;i<N;i++) printf("%d ",Temp->k[i]);
printf("\n");
Q.pop();
}
return 1;
}
Yes, your Node struct is correct.
As to whether there is an easier way it depends. If there is a maximum number of pointers that you will need then an array of pointers would be easier. If you can do it in C++ then an STL vector (can use it like an array, but underneath the hood it can grow dynamically as needed) is easier. If you have to do it in C and it has to be dynamic, though, then no, there is not an easier way.
WDM.H (microsoft header) has a bunch of linked list stuff to look at ( http://msdn.microsoft.com/en-us/library/ff547799(VS.85).aspx ) , I've cut and pasted from that, and added a very simple example.
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY;
typedef struct _MY_THING
{
LIST_ENTRY ListEntry;
ULONG randomdata1;
ULONG randomdata2;
ULONG randomdata3;
ULONG randomdata4;
} MY_THING, *PMY_THING;
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(PCHAR)(address) - \
(ULONG_PTR)(&((type *)0)->field)))
VOID
InsertHeadList(
IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry
)
{
PLIST_ENTRY Flink;
Flink = ListHead->Flink;
Entry->Flink = Flink;
Entry->Blink = ListHead;
Flink->Blink = Entry;
ListHead->Flink = Entry;
}
VOID
InitializeListHead(
IN PLIST_ENTRY ListHead
)
{
ListHead->Flink = ListHead->Blink = ListHead;
}
PLIST_ENTRY
RemoveHeadList(
IN PLIST_ENTRY ListHead
)
{
PLIST_ENTRY Flink;
PLIST_ENTRY Entry;
Entry = ListHead->Flink;
Flink = Entry->Flink;
ListHead->Flink = Flink;
Flink->Blink = ListHead;
return Entry;
}
void main()
{
LIST_ENTRY HeadOfMyList;
MY_THING Thing;
InitializeListHead(&Head);
// example of add thing to list.
InsertHeadList(&HeadOfMyList, &Thing.ListEntry);
// example of removing thing from the list
PLIST_ENTRY listEntry = RemoveHeadList(&HeadOfMyList);
PMY_THING pThing = (PMY_THING) CONTAINING_RECORD(listEntry, MY_THING, ListEntry);
}

Resources