This code adds only one element to the end of list(just creates head element, nothing after that).What is wrong in my program? Should I pass two items in function, head and item or just one?
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct MyList
{
int x;
int y;
struct MyList * next;
}List;
typedef List * Item;
void AddEnd(Item * head);
void PrintList(Item * head);
int main(void)
{
int response;
Item head;
head = NULL;
while(1)
{
printf("1- Print, 2 - Add to End, 3 - exit\n");
scanf("%d", &response);
switch(response)
{
case 1: PrintList(&head); break;
case 2: AddEnd(&head); break;
case 3: return 0;
}
}
return 0;
}
void PrintList(Item * head)
{
Item temp;
temp = *head;
while(temp != NULL)
{
printf("%d %d\n", temp->x, temp->y);
temp = temp->next;
}
}
void AddEnd(Item * head)
{
Item new, temp;
new = (Item)malloc(sizeof(new));
printf("Enter x and y: ");
scanf("%d %d", &new->x, &new->y);
new->next = NULL;
if(*head == NULL)
{
*head = new;
}
else
{
temp = *head;
while(temp != NULL)
{
temp = temp->next;
}
temp = new;
}
}
This code down that I just tried don't work also:
void AddEnd(Item * head, Item * item)
{
Item new, temp;
new = (Item)malloc(sizeof(new));
printf("Enter x and y: ");
scanf("%d %d", &new->x, &new->y);
new->next = NULL;
if(*head == NULL)
{
*head = new;
}
else
{
temp = *head;
while(temp != NULL)
{
temp = temp->next;
}
temp = new;
*item = temp;
}
}
In your AddEnd function in the else clause, when you exit the while loop, temp is now NULL. However, the element before it is still pointing to NULL.
Try something like
temp = *head;
if (temp->next == NULL) {
temp->next = new;
} else {
while((temp->next) != null) {
temp = temp->next;
}
temp->next = new;
}
in your else clause.
(This, and the apparent issue with your understanding of malloc referenced by the others, new should be a Item * and the malloc call should be malloc(sizeof(Item)). You also don't need to cast the return value of malloc (indeed, there are some pitfalls that happen if you do).) Reading your typedefs a little more closely, new should actually be an Item (since it's a pointer to a List struct and you have typedef List* Item). Try new = malloc(sizeof(List)); and just declare new to be of type List *. (The typedef List * Item makes your code hard to read; it becomes less clear what's a pointer and what isn't.)
You need to change this:
new = (Item)malloc(sizeof(new));
To this:
new = (Item *)malloc(sizeof(List));
Hope this helps
Related
I created a standard linked list in C. It asks the user to input a number, and program end if user input #. If the user inputs anything else the program will stop.
The problem is that my program runs forever and prints the normal list at first then keeping print the last element of the linked list.
Hope someone could tell me where did I made mistake.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} NodeT;
void freeLL(NodeT *list) {
NodeT *p, *temp;
p = list;
while (p != NULL) {
temp = p->next;
free(p);
p = temp;
}
}
void showLL(NodeT *list) {
NodeT *temp = list;
temp = temp->next;
printf("Done. The list is ");
printf("%d", temp->data);
temp = temp->next;
//iterate the entire linked list and print the data
while (temp != NULL) {
printf("-->");
printf("%d", temp->data);
temp = temp->next;
}
}
NodeT *joinLL(NodeT *list, int v) {
NodeT *current = list;
NodeT *head;
head->data = v;
head->next = NULL;
while (current->next != NULL) {
current = current->next;
}
current->next = head;
return head;
}
int main() {
int data;
NodeT *list = NULL;
list = (NodeT *)malloc(sizeof(NodeT));
printf("Enter a number: ");
if (scanf("%d", &data) != 1) {
printf("Done. ");
} else {
printf("Enter a number: ");
joinLL(list, data);
while (1 == scanf("%d", &data)) {
printf("Enter a number: ");
joinLL(list, data);
}
showLL(list);
freeLL(list);
}
return 0;
}
I believe the problem is in the joinLL function which add a new node at the end of the linked list.
The problem is you do not allocate elements in joinLL: only a single element in allocated in main().
You should instead always allocate the element in joinLL and update the head pointer from the return value.
Similary, freeLL should take a pointer to head and set it to NULL for consistency.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} NodeT;
void freeLL(NodeT *p) {
while (p != NULL) {
NodeT *temp = p->next;
free(p);
p = temp;
}
}
void showLL(const NodeT *list) {
NodeT *p = list;
printf("The list is ");
if (p == NULL) {
printf("empty");
} else {
printf(" %d", temp->data);
while ((p = p->next) != NULL) {
printf("--> %d", temp->data);
}
}
printf("\n");
}
NodeT *joinLL(NodeT *head, int v) {
NodeT *newp = malloc(sizeof(*p));
NodeT *current;
if (newp == NULL) {
fprintf(stderr, "allocation failure\n");
exit(1);
}
newp->data = v;
newp->next = NULL;
if (head == NULL) {
return newp;
}
for (current = head; current->next != NULL; current = current->next)
continue;
current->next = newp;
return head;
}
int main() {
NodeT *list = NULL;
for (;;) {
int data;
printf("Enter a number: ");
if (scanf("%d", &data) != 1) {
printf("Done. ");
break;
}
list = joinLL(list, data);
}
showLL(list);
freeLL(list);
return 0;
}
Your program keeps running because of a memory access error, you did not allocate memory for your head(you set a pointer, but use it directly without initializing it)
Change to this may solve the problem:
head=(NodeT*)malloc(sizeof(NodeT));
if(NULL==head)
{
// failed : do something...
return NULL;
}
head->data=v;
head->next=NULL;
When I just tested it, I found that there was another problem:
list = (NodeT*)malloc(sizeof(NodeT));
malloc will not be initialize your list, so the value that your list->next initially points to is uncertain.
in c, malloc does not need to be cast.
I made some polynomial code with a doubly-linked list. for example, if
you write 1 and 2 then 1 is a degree and 2 is coefficient. 1x^2 insert
to doubly linked list. the problem is that when I check my code, the Node
head->degree is changing. if I write 1x^2 then head->degree is 1 next,
I write 2x^1 then head-> degree should maintain 1 but head-> degree
change to 2 I think there is some problem in the head pointer.
#include <stdio.h>
#include <stdlib.h>
// struct
struct Node {
int degree;
int coefficient;
struct Node* next;
struct Node* prev;
};
// global variables
int de; // degree
int co; // coefficient
int flag;
Node** head = (Node**)malloc(sizeof(Node)); //
Node** head1 = (Node**)malloc(sizeof(Node)); //
Node** head2 = (Node**)malloc(sizeof(Node)); //
Node** head3 = (Node**)malloc(sizeof(Node)); //
Node* newNode = (Node*)malloc(sizeof(Node)); //
// function
Node* inputpoly(void);
void printNode(Node* inp);
Node* multiply(Node* a, Node* b);
// main
int main() {
// head null
(*head1) = NULL;
(*head2) = NULL;
(*head3) = NULL;
while (1) {
printf("Input (degree) (coefficient) : ");
scanf_s("%d %d", &de, &co);
if (de * co < 0) { continue; }
if (de < 0 && co < 0) {
printf("Done!\n");
break;
}
*head = inputpoly();
}
printNode(*head);
//multiply(*head1, *head2);
free(head1);
free(head2);
free(head3);
free(newNode);
free(head);
}
Node* inputpoly(void) {
// create Node
newNode->degree = de;
newNode->coefficient = co;
newNode->next = NULL;
newNode->prev = NULL;
// case1
if (flag == 0) {
// list
if ((*head1) == NULL) {
*head1 = newNode;
}
// list x
else {
Node* horse = (*head1);
// front of head
// ------------------There is some problem
printf("%d\n", 1);
printf("--%d\n", newNode->degree);
printf("--%d\n", horse->degree);
if (horse->degree > newNode->degree) {
newNode->next = horse;
horse->prev = newNode;
*head1 = newNode;
}
// barward of head
else {
int num = 0;
while (horse->next != NULL) {
horse = horse->next;
if (horse->degree > newNode->degree) {
horse->prev->next = newNode;
newNode->next = horse;
newNode->prev = horse->prev;
horse->prev = newNode;
num = 1;
break;
}
}
// behind tail
if (num == 0) {
horse->next = newNode;
newNode->prev = horse;
}
}
}
return *head1;
}
}
void printNode(Node* inp) {
Node* horse = inp;
if (horse == NULL)
{
return;
}
while (horse != NULL) {
if (horse->prev == NULL) {
if (horse->degree == 1) {
printf("%d", horse->coefficient);
}
else {
printf("%d x^%d", horse->coefficient, horse->degree);
}
}
else {
if (horse->degree == 1) {
printf(" + %d", horse->coefficient);
}
else {
printf(" + %d x^%d", horse->coefficient, horse->degree);
}
}
}
printf("\n");
}
"i think there is some head pointer problem, and if I fixed it I can this problem. so I want to maintain this code as possible. I want some
advice or solution to my head pointer"
The code posted in your example does not compile:
Before you can fix a head pointer problem the code must compile. This list of errors is detailing 2 things:
first, functions cannot be called outside of a function, eg:
Node** head = (Node**)malloc(sizeof(Node)); //
Node** head1 = (Node**)malloc(sizeof(Node)); //
Node** head2 = (Node**)malloc(sizeof(Node)); //
Node** head3 = (Node**)malloc(sizeof(Node)); //
Node* newNode = (Node*)malloc(sizeof(Node)); //
should be called from within main(void){...} or some other function.
second, every occurrence of Node should be prepended with struct. eg:
struct Node** head = malloc(sizeof(struct Node *));
(have also removed the cast, and modified the size of what you are creating memory for, i.e. a pointer)
Rather then fix these and other problems, here is an example of a doubly linked list that can demonstrate the structure of a simple working program. You can adapt the following to match your needs:
struct Node {
int deg;
int coef;
struct Node* next; // Pointer to next node in DLL
struct Node* prev; // Pointer to previous node in DLL
};
void inputpoly(struct Node** head_ref, int deg, int coef)
{
//allocate node
struct Node *new_node = malloc(sizeof(*new_node));
//assign data
new_node->deg = deg;
new_node->coef = coef;
//set next as new head and prev to null
new_node->next = (*head_ref);
new_node->prev = NULL;
//change prev of head to new */
if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;
//point head to the new node */
(*head_ref) = new_node;
}
void printList(struct Node* node)
{
struct Node* last;
printf("\nread forward\n");
while (node != NULL) {
printf(" %d,%d ", node->deg,node->coef);
last = node;
node = node->next;
}
printf("\nread reverse\n");
while (last != NULL) {
printf(" %d,%d ", last->deg,last->coef);
last = last->prev;
}
}
int main(void)
{
//start with empty list
struct Node* head = NULL;
//create and populate new nodes
inputpoly(&head, 7, 2);
inputpoly(&head, 1, 4);
inputpoly(&head, 4, 6);
//ouput list
printList(head);
getchar();
return 0;
}
Note that this code is offered as a basic demonstration of creating doubly linked list, and illustrate how to traverse both directions. Because it does not free allocated memory, it is not recommended that it be used for any production purpose without addressing that omission.
Memory error with freeing a linked list that contains an int and next only.
I have tried the following function that is shown in the beginning of the code.
This program recieves the number of nodes in the linked list and a value for each node. Next, the program asks for the number of rotations (k) for the list and rotate the list k numbers to the left. The function works well until freeing the memory that was allocated.
The error happens in the free(temp) line "Debug error HEAP CORRUPTION DETECTED".
#include <stdio.h>
#include <stdlib.h>
typedef struct IntNode
{
int val;
struct IntNode* next;
} IntNode;
void printList(IntNode* list);
void freeList(IntNode* head);
IntNode* createNode(int val);
void moveKPlaces(IntNode** list, int k);
int numNodes = 0;
int main(void)
{
IntNode* list = NULL;
IntNode* curr = list;
IntNode* newNode = NULL;
int i = 0, num = 0, k = 0;
printf("How many nodes in list? ");
scanf("%d", &numNodes);
getchar();
for (i = 0; i < numNodes; i++)
{
printf("Enter number: ");
scanf("%d", &num);
getchar();
if (i == 0)//head of the list
{
newNode = createNode(num);
list = newNode;
curr = list;
}
else
{
while (curr->next != NULL)
{
curr = curr->next;
}
newNode = createNode(num);
curr->next = newNode;
newNode->next = NULL;
}
}
printf("Choose a number k, and the list will be rotated k places to the left: ");
scanf("%d", &k);
getchar();
printf("The rotated list:\n");
moveKPlaces(&list, k);
printList(list);
freeList(list);
getchar();
return 0;
}
/*
This function recieves a pointer to a pointer to the head of a list and
a number (k) and rotate the list k places to the left.
input:
a pointer to a pointer to the head of a list and
a number (k)
output:
none
*/
void moveKPlaces(IntNode** list, int k)
{
IntNode* curr = *list;
IntNode* last = NULL;
IntNode* head = *list;
int placeNode = 0;
while (curr->next != NULL)
{
curr = curr->next;
}
curr->next = head;//turn it to a circular list
while (placeNode < k)
{
curr = curr->next;
placeNode++;
}
*list = curr->next;// the k node will be the head
curr->next = NULL;// the one before will be the last
}
//************************************
// Method: printList
// Returns: void
// Description: prints list recursively
// Parameter: IntNode * list
//************************************
void printList(IntNode* list)
{
if (list)
{
printf("%d ", list->val);
printList(list->next);
}
else
{
printf("\n");
}
}
void freeList(IntNode* head)
{
IntNode* temp = NULL;
IntNode* curr = head;
while (curr)
{
temp = curr;
curr = (curr)->next;
free(temp);
}
head = NULL;
}
IntNode* createNode(int val)
{
IntNode* newNode = (IntNode*)malloc(sizeof(newNode));//will alocate every person node dinamically
newNode->val = val;
// insert all details
newNode->next = NULL;
return newNode;
}
Expected free without any error
"Debug error HEAP CORRUPTION DETECTED".
IntNode* newNode = (IntNode*)malloc(sizeof(newNode));//will alocate every person node dinamically
That doesn't allocate enough space. It should be sizeof(*newNode) or sizeof(IntNode).
I am new to C and try to learn how to implement C on linked list. I am really confused why I can't access myList in the main function? because when I try to myList->data, it's segmentation fault. I think there's some error in my addtohead function?
Below is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct NODE{
int data;
struct NODE *next;
}node;
node * myList;
node * addToHead(node*, int);
void printList();
int main(){
myList = NULL;
int input;
while (scanf("%i",&input) == 1){
addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
void printList(node* head){
node *temp = head;
while(temp != NULL){
printf("%d ", temp->data);
temp = temp -> next;
}
printf("\n");
}
Your addToHead function is supposed to return the mallocated memory back to caller.
So you should assign the return value to mylist at first:
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1){
myList = addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
Into your addToHead function you wrote
head = temp;
But head has local scope and the assigned value is not reflected to the pointer myList.
To do so you have to use pointer to pointer.
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1)
{
if (addToHead(&myList, input) == true)
{
printf("%d \n", myList->data);
}
else
{
fprintf(stderr, "Error addToHead\n");
}
}
return 0;
}
bool addToHead(node** head, int newData){
node *temp = malloc(sizeof(node));
if (temp != NULL)
{
temp -> data = newData;
temp -> next = NULL;
if(head != NULL)
{
temp -> next = *head;
}
*head = temp;
return true;
}
return false;
}
Finally always remember to check the malloc return value: it can fail.
You return the new head node from addToHead, but you don't do anything with it. You need to assign this value to myList to update it:
myList = addToHead(myList, input);
Also, you misspelled a variable on the following line:
printf("%d \n", myListd->data);
It should be:
printf("%d \n", myList->data);
In this function definition
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
The parameter node* head is a local variable of the function. Any changes of the parameter will not influence on the original argument. The function parameters will be destroyed after exiting the function.
You can consider the function definition and its call the following way
addToHead(myList, input);
//...
node* addToHead(/*node* head, int newData*/){
node *head = myList;
int newData = input;
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
So the original variable myList will not be changed after the function call. You have to assign explicitly the returned value to the variable
myList = addToHead(myList, input);
Also the function has a drawback. It does not report an error in case when the new node was not allocated.
A better approach to write the function looks the following way
int /* _Bool */ addToHead( node **head, int newData )
{
node *temp = ( node * )malloc( sizeof( node ) );
int /* _Bool */ success = temp != NULL;
if ( success )
{
temp -> data = newData;
temp -> next = *head;
*head = temp;
}
return success;
}
In this case the function can be called in a loop the following way
while ( scanf( "%i", &input ) == 1 && addToHead( &myList, input ) )
{
//...
}
We have a problem with our LinkedList in C.
When I count how many nodes should be in the list, I always get 1
LL count: 1
This is the Add, count and get last element of the list code:
void addLL(LL * head)
{
LL *newNode;
LL *tail = getLastNode(head);
newNode = malloc(sizeof(LL));
if(newNode != DEF_NULL)
{
newNode->ID=-1;
newNode->TCB=-1;
newNode->next = DEF_NULL;
if(!head) head = newNode;
else tail->next = newNode;
}
}
LL * getLastNode(LL * head)
{
LL *temp = head;
while(temp->next != DEF_NULL)
{
temp = temp->next;
}
return temp;
}
CPU_INT32U countLL(LL * head)
{
CPU_INT32U elements = 0;
LL * temp = head;
while(temp->next != DEF_NULL)
{
temp = temp->next;
elements++;
}
return elements;
}
It's called in this way:
addLL(list);
temp = countLL(list);
Debug_LOG("LL count: %i", temp);
where LL * list; is a global variable, and temp is in local scope.
I hope anyone can see where I went wrong
Greetings,
Sjaak and Gerrit
I see several issues in your code :
you should always protect your linked list operations by testing if the list pointer is valid (i.e. not null)
you cannot allocate a first item to an empty list due to the way you allocate the first new item : you change head but the modification won't be propagated outside of the function. You should pass a "pointer to a list pointer" (i.e. a LL**) that is equivalent to "the address of a LL*"; See how I call addLL() and how I have modified its prototype and the head assignment
if your list is only one block long, it won't be counted as you count only if there is a successor, see how I have modifed the order of the do / while condition
I propose the modified code that works for 1, 2 or any list length (I have just changed the CPU_INT32U to int to compile quickly with MinGW, I could have typedef'ined):
#include <stdio.h>
#define DEF_NULL 0
typedef struct tagL {
int ID;
int TCB;
struct tagL *next;
} LL;
void addLL(LL ** head);
LL * getLastNode(LL * head);
int countLL(LL * head);
void addLL(LL ** head)
{
LL *newNode;
LL *tail = getLastNode(*head);
newNode = malloc(sizeof(LL));
if(newNode != DEF_NULL)
{
newNode->ID=-1;
newNode->TCB=-1;
newNode->next = DEF_NULL;
if(!*head)
*head = newNode;
else
tail->next = newNode;
}
}
LL * getLastNode(LL * head)
{
LL *temp = head;
if (head){
while(temp->next != DEF_NULL)
{
temp = temp->next;
}
}
return temp;
}
int countLL(LL * head)
{
int elements = 0;
LL * temp = head;
if (head){
do {
temp = temp->next;
elements++;
} while(temp != DEF_NULL);
}
return elements;
}
int main(int argc, char *argv[]){
LL *list = 0;
printf("LL test\n");
addLL(&list);
printf("length = %d\n", countLL(list));
addLL(&list);
printf("length = %d\n", countLL(list));
addLL(&list);
printf("length = %d\n", countLL(list));
}
Output :
LL test
length = 1
length = 2
length = 3
On Windows nothing's wrong whit this function - strange ...
ideone also shows good output.
#include <stdio.h>
#include <stdlib.h>
typedef struct LL{
struct LL *next;
}LL;
LL * getLastNode(LL * head)
{
LL *temp = head;
while(temp->next != NULL)
{
temp = temp->next;
}
return temp;
}
void addLL(LL * head)
{
LL *newNode;
LL *tail = getLastNode(head);
newNode = malloc(sizeof(LL));
if(newNode != NULL)
{
newNode->next = NULL;
if(!head) head = newNode;
else tail->next = newNode;
}
}
int countLL(LL * head)
{
int elements = 0;
LL * temp = head;
while(temp->next != NULL)
{
temp = temp->next;
elements++;
}
return elements;
}
int main() {
LL *h = malloc(sizeof(*h));
addLL(h);
addLL(h);
addLL(h);
printf("%d\n", countLL(h)); // prints 3 as expected
}
CPU_INT32U countLL(LL * head){CPU_INT32U elements = 0;LL * temp = head;while(temp->next != DEF_NULL){temp = temp->next;elements++;}return elements;}
in this function you are declaring elements variable as auto
so its storage gets deallocated as soon as function exits , as memory now free to allocate to different variable, so may be overwritten hence previous cvalue gets lost
so to avoid this please use static in declaring variable.....
as static variables memory gets deallocated only after execution of whole program
please try....
void addLL(LL * head)
{
LL *newNode;
LL *tail = getLastNode(head);
There is a problem here, if (the global) head happens to be NULL, it will be dereferenced by the getLastNode() function:
LL * getLastNode(LL * head)
{
LL *temp = head;
while(temp->next != DEF_NULL)
Here temp->next != ... will cause temp to be dereferenced. That would cause NULL pointer dereferences if temp happens to be NULL. (as in the call by the insert function. You could add an extra test (or use pointers to pointers which is cleaner):
while(temp && temp->next != DEF_NULL)
Update (to show that the pointer to pointer version is cleaner)
#include <stdlib.h>
#include <stdio.h>
#define DEF_NULL NULL
#define CPU_INT32U unsigned
typedef struct link {
struct link *next;
} LL;
LL *globhead=NULL;
LL **getTailPP(LL **ppHead);
CPU_INT32U countLL(LL * ptr);
void addLL(LL **ppHead);
void addLL(LL **ppHead)
{
ppHead = getTailPP(ppHead);
*ppHead = malloc(sizeof **ppHead);
if(*ppHead != DEF_NULL)
{
// newNode->ID=-1;
// newNode->TCB=-1;
(*ppHead)->next = DEF_NULL;
}
}
LL **getTailPP(LL **ppHead)
{
for( ; *ppHead; ppHead = &(*ppHead)->next ) {;}
return ppHead;
}
CPU_INT32U countLL(LL * ptr)
{
CPU_INT32U elements = 0;
for(; ptr != DEF_NULL; ptr=ptr->next) { elements++; }
return elements;
}
int main()
{
unsigned count;
addLL( &globhead);
count = countLL (globhead);
printf("count = %u\n", count);
addLL( &globhead);
count = countLL (globhead);
printf("count = %u\n", count);
return 0;
}