Error in Display the linked list - c

Folks,
I don't know whether I am asking silly question. But tried to figure out my problem, but fail to that.
my structure is
typedef struct {
uint16 nwkaddr;
uint8 extaddr[8];
}device_t;
typedef struct node{
device_t list;
struct node *link;
}address_list;
The Data coming from UART is
1010,23CD1234,CD32454F,12F439AF,! . This I need to parse and store the mac list.
while(data[j] != '!')
{
if(data[i] == ',')
{
i = i+1;
memset(addr, 0, 9);
memcpy(addr, &data[i], 8);
// addr[8] = '\0';
if(addr != 0)
{
insert_MacList(addr);
}
}
i = i+8;
j = i+1;
}
the Created list is
void insert_MacList(uint8 *mac)
{
address_list *curr, *temp;
//curr = (address_list*)malloc(sizeof(address_list));
curr = osal_mem_alloc(sizeof(address_list));
strcpy((char*)curr->list.extaddr, (char const*)mac);
temp = head;
if(head == NULL)
{
head = curr;
head->link = NULL;
}
else
{
while(temp->link !=NULL)
{
temp = temp->link;
}
curr->link = NULL;
temp->link = curr;
}
}
I am trying to print all address,But I am fail to get 23CD1234. But after that I am getting correctly.
void check_inlist(void)
{
address_list *temp;
temp = head;
while(temp != NULL)
{
/*print data and send to UART*/
temp = temp->link;
}
}
Why head is changing to second element, is 23 value creating some problem?. So can some help me

You are using strcpy to copy data that isn't null terminated!
You can change it like this:
strncpy((char*)curr->list.extaddr, (char const*)mac, sizeof curr->list.extaddr); // strncpy won't write past the end of the array

You have
typedef struct {
uint16 nwkaddr;
uint8 extaddr[8];
}device_t;
But in insert_MacList() you call
strcpy((char*)curr->list.extaddr, (char const*)mac);
what copies 9 bytes (8 values + terminating '\0'). That might cause the problem.

Related

i want to make sure that my linked list work

Is this a right way to do a linked list ? I am having a problem in a big school project and now i want to make sure that this is true.
void addnode(int a){
struct house* tmp = houses[i].next;
while (tmp != NULL) {
tmp = tmp->next;
}
tmp = (struct house*)malloc(sizeof(struct house));
tmp->id=a;
tmp->next=NULL;
}
i figured out that the error can be in other parts of the code. Now i will share the parts i suspect i hope you can help me.
houses[i] is an array of linked lists. if houses[i].id==-1 it is empty
struct house get_house_byid(int id) {
for (int i = 0; i < 1000; i++) {
if (houses[i].id != -1) {
if (houses[i].id == id) {
return houses[i];
}
if (houses[i].next != NULL) {
struct house* tmp = houses[i].next;
while (tmp != NULL) {
if (tmp->id == id) {
return *tmp;
}
tmp = tmp->next;
}
}
}
}
struct house housep;
housep.id = -1;
return housep;//if it cant find that id it returns housep
}
There may be other issues with your code that is not shown, but there are issues with addnode:
addnode does not set the head of the list (i.e. houses[i].next).
Thus, the newly added node is never connected to anything [and is a memory leak].
Ignoring the [obvious] typo/syntax error: void addnode{int a} instead of void addnode(int a).
The loop on tmp discards the pointer to the tail of the list. We need a separate variable (e.g. prev).
Note that i is global. That's fine, but the function would be cleaner if i was an argument to addnode instead.
Don't cast the return of malloc: Do I cast the result of malloc?
Here's is some refactored code. It is annotated:
void
addnode(int i,int a)
{
struct house *tmp;
struct house *prev;
// find the tail of the list
prev = NULL;
for (tmp = houses[i].next; tmp != NULL; tmp = tmp->next)
prev = tmp;
// allocate the new node
tmp = malloc(sizeof(*tmp));
tmp->id = a;
tmp->next = NULL;
// append to the tail of the [non-empty] list
if (prev != NULL)
prev->next = tmp;
// add to front of the empty list
else
houses[i].next = tmp;
}

C: getchar() destroys pointer

typedef struct LinkedList LinkedList;
struct LinkedList {
LinkedList* next;
char* head;
char current;
};
LinkedList makeList()
{
char* headPointer = calloc(60, sizeof(char));
LinkedList temp = { 0xCCCCCCCC, headPointer, 0 };
return temp;
}
int addToList(LinkedList* lstPointer, char toAdd) {
if (lstPointer->head == NULL || lstPointer->head == 0xCCCCCCCC)
return -1;
if (lstPointer->current + 1 < 60) { /* enough space in the list to add */
*(lstPointer-> head + lstPointer -> current) = toAdd;
lstPointer->current = lstPointer->current + 1;
}
else /* not enough space, will create new node in the list */
{
if (lstPointer->next == 0xCCCCCCCC) {
LinkedList nextNode = makeList();
lstPointer->next = &nextNode;
}
return addToList(lstPointer->next, toAdd);
}
/*Added succsessfully*/
return 0;
}
int main(){
char chr;
LinkedList lst = makeList();
while ((chr = getchar()) != EOF) {
if (addToList(&lst, chr) == -1)
return -1;
}
return 0;
}
i am trying to use linked list but after i fill the first, i create a new one and able to add an item to it. on the second item the next list pointer get destroyed by getchar(). i have no idea why or how is it related.
In makelist you need to allocate a new list, but then instead of returning it, you copy it into a local variable, leaking the memory that you just allocated. Instead, return a pointer:
LinkedList *makeList() // Note *
{
LinkedList *temp = calloc(1, sizeof(LinkedList));
temp->head = calloc(60, sizeof(char));
temp->next = 0;
temp->current = toAdd;
return temp; // Note temp is a pointer
}
In addToList you don't need the nextNode variable:
lstPointer->next = makelist();

Comparing 2 strings from a struct

I don't program in C for a good 2 years, I recently was ordered to make a program that uses a FIFO system, I'm really confused about how I'm going to search for a name using this method.
This is my struct:
struct Node {
int price;
char plat[25];
char name[50];
struct Node *next;
};
typedef struct Node node;
This is where I insert:
void insert(node *LINE) {
line *new = alocar();
new->next = NULL;
if (empty(LINE))
LINE->next = new;
else {
node *tmp = LINE->next;
while (tmp->next != NULL)
tmp = tmp->next;
tmp->next = new;
}
size++;
}
Here is where I'm struggling, I'm just freestyling at this point, trying to figure out what works but nothing seems to be working, I'm trying to search for the name inside the struct using the nameu variable.
void search(node*LINE)
{
if(empty(LINE))
{
printf("Line empty!\n\n");
return;
}
// -------------------test----------------------
char nameu[10];
node *tmp;
node n;
if (scanf("%9s", nameu) != 1) return;
while( tmp != NULL && strcmp(nameu, n.name) == 0)
{
printf("%6s", tmp->name);
tmp = tmp->prox;
}
}
The full code is in Portuguese so I only placed snippets of code that I translated, I'll post here the full code with translations only in the menu so that anyone trying to use it can comprehend what's going on.
https://pastebin.com/ZytqhcWF
Edit: Thanks to Dimitri and the others I found the cause of it not printing, here is the result.
void search(node*LINE)
{
if(empty(LINE))
{
printf("Line empty!\n\n");
return;
}
// -------------------test----------------------
char nameu[10];
node *tmp;
tmp = LINE->next;
node n;
if (scanf("%9s", nameu) != 1) return;
while (tmp)
{
if (!strcmp(nameu, tmp->name))
{
printf("%6s", tmp->name);
break;
}
tmp = tmp->next;
}

Unexpect behaviour with pointer array

im currently implementing a basic linked list structure on C.
Basically im parsing a txt file, and I buffer each line into a Node which contains a pointer to an array of integers. The problem is, that my data (the array of integers) doesn't save correctly / i don't know how to iterate through it correctly.
These are the structures that I use:
typedef struct Node
{
struct Node* next;
struct Node* prev;
int* data;
int len;
} Node;
typedef struct LinkedList
{
Node* head;
Node* tail;
} LinkedList;
and I use this method to create a new node from a buffered string:
int nodeManager(FILE* filePointer, char* buffer, char* token, LinkedList* linkedList)
{
token = strtok(buffer, DELIMITER);
int* data = (int*)malloc(sizeof(int));
int dataIndex = 0;
if (data == NULL)
{
fprintf(stderr, DATA_ALLOCATION_ERROR);
freeLinkedList(linkedList);
fclose(filePointer);
return EXIT_FAILURE;
}
const char* insertPosition = token;
while ((token = strtok(NULL, DELIMITER)))
{
data = realloc(data, dataIndex + 1);
if (data == NULL) {
fprintf(stderr, DATA_ALLOCATION_ERROR);
freeLinkedList(linkedList);
fclose(filePointer);
return EXIT_FAILURE;
}
char *res;
int num = (int) strtol(token, &res, 10);
data[dataIndex] = num;
dataIndex++;
}
Node* newNode = (Node*)malloc(sizeof(Node));
if (newNode == NULL)
{
freeLinkedList(linkedList);
free(data);
fclose(filePointer);
return EXIT_FAILURE;
}
newNode -> prev = NULL; newNode -> next = NULL;
newNode -> len = dataIndex; newNode -> data = data;
if(strcmp(insertPosition, INSERT_TO_START) == 0)
{
addToStartLinkedList(linkedList, newNode);
}
else
{
addToEndLinkedList(linkedList, newNode);
}
return EXIT_SUCCESS; // TODO - Change
}
A line of input looks like this:
start,1,2,3,4,5,6,7,10,22,44,55,66,66,77
for some reason, node -> data doesn't get all the values that I assign in this method and I can't really tell why.
I tried to print the values like this:
for (int i = 0; i < newNode -> len; i++)
{
printf("%d,", (newNode -> data)[i]);
}
However, as I said, something quite doesn't work with my assigment, or I just don't know how to access the values correctly.
Would love to get some insight - thanks.
This part is wrong:
data = realloc(data, dataIndex + 1);
You have forgotten to multiply with sizeof(int) or better sizeof *p
BTW: Be careful about doing realloc directly into data. On failure realloc may return NULL and then you have a memory leak. You should use a temporary pointer like:
int * temp = realloc(data, SOME_SIZE);
if (temp == NULL)
{
// oh dear, add error handling here - maybe a return or whatever fits
}
else
{
// All good
data = temp;
}
OT: Passing the file pointer to the function in order to be able to close the file is (IMO) a rather strange design. Instead, the caller should check the return value and close the file (if desired).

Mergesort on a linked-list using only one function, segmentation fault

I need to implement the function: struct listnode * mergesort(struct listnode *data)
My professor provided the main() function testing code. I only need to submit the mergesort function. He told us to do it in C or C++ but the test code main() he gave us is in C.
This is my code right now:
I can compile it but when I run it, it crashes. I checked debugger and it gave me segmentation fault. I am also not really sure if this function is correct since I can't get past the testing point in the main().
#include <stdio.h>
#include <stdlib.h>
struct listnode { struct listnode * next;
long value; } ;
struct listnode * mergesort(struct listnode *data)
{ int temp, finished = 0;
struct listnode *tail, *head, *ahead, *bhead, *atail, *btail;
if ( data == NULL )
return;
//Split
ahead = atail = head = data; // first item
btail = head->next; // second item
while(btail->next != NULL) // anything left
{
atail = atail->next;
btail = btail->next;
if( btail->next != NULL)
btail = btail->next;
}
bhead = atail->next; // disconnect the parts
atail->next = NULL;
//sort
mergesort(ahead);
mergesort(bhead);
//merge
if(ahead->value <= bhead->value) // set the head of resulting list
head = tail = ahead, ahead = ahead->next;
else
head = tail = bhead, bhead = bhead->next;
while(ahead && bhead)
if(ahead->value <= bhead->value) // append the next item
tail = tail->next = ahead, ahead = ahead->next;
else
tail = tail->next = bhead, bhead = bhead->next;
if(ahead != NULL)
tail->next = ahead;
else
tail->next = bhead;
return(head);
}
int main(void)
{
long i;
struct listnode *node, *tmpnode, *space;
space = (struct listnode *) malloc( 500000*sizeof(struct listnode));
for( i=0; i< 500000; i++ )
{ (space + i)->value = 2*((17*i)%500000);
(space + i)->next = space + (i+1);
}
(space+499999)->next = NULL;
node = space;
printf("\n prepared list, now starting sort\n");
node = mergesort(node);
printf("\n checking sorted list\n");
for( i=0; i < 500000; i++)
{ if( node == NULL )
{ printf("List ended early\n"); exit(0);
}
if( node->value != 2*i )
{ printf("Node contains wrong value\n"); exit(0);
}
node = node->next;
}
printf("Sort successful\n");
exit(0);
}
if ( data == NULL )
return;
You should return NULL.
btail = head->next; // second item
while(btail->next != NULL) // anything left
{
If btail is set to head->next. If head->next is NULL, you're trying to check in the loop NULL->next != NULL which isn't a thing.
if( btail->next != NULL)
btail = btail->next;
}
You need to check if btail is NULL before you check ->next. Just above you are setting btail = btail->next; so it could be set to NULL.
Also the loop above has the same issue, you need to check null before you do stuff with next.
There may be issues with the below code, but the above code needs way more error checking.
Example function to merge two already sorted lists using pointer to pointer. Since your'e only allowed a single function, you'll have to merge this logic into your mergesort() function. If this is homework, it may seem like you had too much help, but I'm not sure how else to explain the ideas shown in this example.
NODE * MergeLists(NODE *pSrc1, NODE *pSrc2)
{
NODE *pDst = NULL; /* destination head ptr */
NODE **ppDst = &pDst; /* ptr to head or prev->next */
while(1){
if(pSrc1 == NULL){
*ppDst = pSrc2;
break;
}
if(pSrc2 == NULL){
*ppDst = pSrc1;
break;
}
if(pSrc2->data < pSrc1->data){ /* if src2 < src1 */
*ppDst = pSrc2;
pSrc2 = *(ppDst = &(pSrc2->next));
continue;
} else { /* src1 <= src2 */
*ppDst = pSrc1;
pSrc1 = *(ppDst = &(pSrc1->next));
continue;
}
}
return pDst;
}

Resources