counting redundancies in linked list in C - c

I'm practicing code that can find redundancies in a linked list.
For example:
INPUT
777
OUTPUT
contains 2 redundancies
INPUT
32182
OUTPUT
contains 1 redundancies
I'm struggling to actually track redundancies in my code. I'v sorted the linked list, then I assume I would just create 2 pointers one that traverses the current location of the linked list and one that traverses the previous location of the linked list and if they're equal count++. But I always get 0 redundancies.
In the code below, I think my challenge is mainly in the countRedun() method.
struct digit * insertAtFront(struct digit *start, struct digit * newDig){
struct digit * ptr = start;
newDig = start;
return newDig;
}
struct digit * insertIntoSorted(struct digit *start, struct digit *newDig) {
struct digit *ptr = start;
struct digit *prev = NULL;
while ((ptr!=NULL) && (ptr->num < newDig->num)) {
prev = ptr;
ptr = ptr->next;
}
if (prev == NULL) {
start = insertAtFront(start, newDig);
} else {
prev->next = newDig;
newDig->next = ptr;
}
return(start);
}
struct digit * sortedCopy(struct digit * start) {
//! heap1=showMemory(start=348, cursors=[start, ptr, sortedStart, newDigit])
//! heap2=showMemory(start=519, cursors=[start, newDigit, ptr, prev])
struct digit *ptr = start;
struct digit *sortedStart = NULL;
struct digit *newDigit;
if (start!=NULL) {
sortedStart = createDigit(start->num);
ptr = ptr->next;
}
while (ptr!=NULL) {
newDigit = createDigit(ptr->num);
sortedStart = insertIntoSorted(sortedStart, newDigit);
ptr = ptr->next;
}
return(sortedStart);
}
int countRedun(struct digit * start){
struct digit *sorted, *ptr, *prev, * curr;
ptr = start;
prev = start;
//sort linked list
sorted = sortedCopy(start);
int count = 0;
while(ptr != NULL)
{
if(ptr->num == prev->num)
{
count++;
}
prev = ptr;
ptr = ptr->next;
}
}
I've excluded the code that asks user for input, as well as the linked list creator methods, assuming that the sorting, and counting methods are key for this question.

It looks like sortedCopy makes a whole new list, but sorted. If so, then you need to reorder:
ptr = start;
prev = start;
//sort linked list
sorted = sortedCopy(start);
with:
//sort linked list
sorted = sortedCopy(start);
ptr = sorted;
prev = sorted;
as a note, you would likely be better to:
prev = NULL;
while(ptr != NULL) {
count += (prev && ptr->num == prev->num);
prev = ptr;
ptr = ptr->next;
}
otherwise you count will always be off by one.

I think the issue is in insertAtFront
struct digit * insertAtFront(struct digit *start, struct digit * newDig){
struct digit * ptr = start;
newDig = start;
return newDig;
}
Remember that everything is passed by value. Your ptr variable isn't used at all, and in this function start and newDig are local variables. Really this is equivalent to:
struct digit * insertAtFront(struct digit *start, struct digit * newDig){
return start;
}
Have another look at that function. I'm not sure of your context but you can use a debugger or printf statements to see what's going on.

If you are sure that:
all you need to do is get the number of redundancies
your input is always going to be a digit between 0 and 9
Then you don't need to sort the data (which, by the way, you're doing in O(n^2) time complexity).
All you need to do is keep an array with 10 elements initialized to 0, increase the corresponding index to your element and count the elements with value greater than 1.
Something along the lines of this (beware: NOT tested):
int countRedun(struct digit * start){
int counter[10] = {0};
struct digit *ptr = start;
int total = 0;
while(ptr != NULL)
{
counter[ptr->num]++;
ptr = ptr->next;
}
for (int i = 0; i < 10; i++) {
if (counter[i] > 1) {
total += counter[i] - 1;
}
}
return total;
}

Related

Very strange behavior with printf in C program

I'm currently working on a lesson in the free edX.org C Programming course. I'm working through the final examples on linked list and playing around with the code below. This code is not complete yet, but what I'm baffled by is that when uncommenting the commented line in main, none of the printf statements give output to the console. Even the printfs before that line.
When I run it I'm simply entering 123 and then pressing the enter key.The printfs output fine as long as the line is commented out. I should also mention that when setting breakpoints around the printfs while it's commented out, it appears the program is continuing to execute through and past the breakpoints, but no output appears on the console.
Could anyone give insight into why this is happening? I'm running this in STM32CubeIDE on Fedora Linux with GCC toolchain. Please let me know if I could provide more detail. Thanks.
#include <stdio.h>
#include <stdlib.h>
struct digit {
int num;
struct digit *next;
};
struct digit * createDigit(int);
struct digit * append(struct digit * end, struct digit * newDigptr);
void printNumber(struct digit *);
void freeNumber(struct digit *start);
struct digit * readNumber();
struct digit * searchNumber(struct digit * start, int number);
struct digit * reverseNumber(struct digit* start);
int main(void) {
struct digit *start, *backwards;
printf("Please enter a number: ");
start = readNumber();
printf("a\n");
printNumber(start);
printf("b\n");
//backwards = reverseNumber(start);
printf("c\n");
freeNumber(start);
return 0;
}
struct digit *createDigit(int dig) {
struct digit *ptr;
ptr = (struct digit *) malloc(sizeof(struct digit));
ptr->num = dig;
ptr->next = NULL;
return ptr;
}
struct digit * append(struct digit * end, struct digit * newDigptr) {
end->next = newDigptr;
return(end->next);
}
void printNumber(struct digit *start) {
struct digit * ptr = start;
while (ptr != NULL) {
printf("%d", ptr->num);
ptr = ptr->next;
}
printf("\n");
}
void freeNumber(struct digit *start) {
struct digit * ptr = start;
struct digit * tmp;
while (ptr != NULL) {
tmp = ptr->next;
free(ptr);
ptr = tmp;
}
}
struct digit * readNumber() {
char c;
int d;
struct digit *start, *end, *newptr;
start = NULL;
scanf("%c", &c);
while (c!='\n') {
d = c - 48;
newptr = createDigit(d);
if (start == NULL) {
start = newptr;
end = start;
}
else {
end = append(end, newptr);
}
scanf("%c", &c);
}
return start;
}
struct digit * searchNumber(struct digit * start, int number) {
struct digit * ptr = start;
while (ptr != NULL && ptr->num != number) {
ptr = ptr->next;
}
return(ptr);
}
struct digit* reverseNumber(struct digit* start) {
// iterate the original list and for each element make it the end in the new list
struct digit *next, *newListStart;
newListStart = next = start;
if (newListStart == NULL)
printf("yay");
else
printf("nay");
while (next != NULL) {
next = next->next;
newListStart->next = createDigit(newListStart->num);
newListStart = createDigit(next->num);
}
return newListStart;
}
The issue is your newListStart = createDigit(next->num). Trying to access num results in a dereference of a null pointer (you cannot access *next's fields since it isn't pointing to anywhere).

Splitting C linked list without making a copy

I have this struct:
typedef struct node {
struct node *m_Next;
int id;
} NODE;
And I need to split linked list in half. If it can't be split into two same halves, I want to remove the last one from the bigger list.
Example: The whole list: {1,2,3,4,5}; What I need: A:{1,2} B:{3,4} (The last one is discarded)
I have this function to separate the list:
void split(NODE *src, NODE **p1, NODE **p2) {
int len = get_length(src);
if (len < 2) {
*p1 = NULL;
*p2 = NULL;
return;
}
struct node *current = src;
int c = (len - 1) / 2;
for (int i = 0; i < c; i++) {
current = current->m_Next;
}
*p1 = src;
*p2 = current->m_Next;
current->m_Next = NULL;
}
It works fine with even lists, but when I try to separate something with 7 structs, I have two problems:
a) The last one doesn't point to NULL
b) It shuffles the data somehow (I expect: A:{1,2,3} B:{4,5,6} | I get: A:{1,2,3} B:{5,4,7} for example)
Could anyone please help me splitting the list correctly and adding the even/odd condition?
I already have the function to delete the last struct:
deleteNode(struct TSoldier *firstNode)
I just don't use it currently, because the split function is bugged.
Thanks :)
First of all, it is worth noting that the following code probably causes a memory leak:
if (len < 2) {
*p1 = NULL;
*p2 = NULL;
return;
}
If the number of nodes is equal to 1, then, unless you keep some other reference to this node, the memory will be leaked. You probably have such a reference outside the function, but you are probably discarding this reference and only keeping the values written to p1 and p2, which means the memory is leaked.
Therefore, assuming that you allocated the node with malloc, you will probably want to add the line
free( src );
in order to prevent the memory leak, or use your function deleteNode.
As already pointed out in the other answer, the line
int c = (len - 1) / 2;
is wrong. It should be:
int c = len / 2 - 1;
At the end of your function split, if the number of nodes is odd, you must add code to discard the final node, for example like this:
if ( len % 2 == 1 )
{
current = *p2;
for (int i = 0; i < c; i++) {
current = current->m_Next;
}
free( current->m_Next );
current->m_Next = NULL;
}
To determine the last node of the first half, instead of int c = (len - 1) / 2; you should use this formula that works for even and odd lengths:
int c = len / 2 - 1;
Similarly, to drop the last node if the length is odd and greater than 1:
if (len & 1) {
NODE *node = src;
for (int i = 2; i < len; i++) {
node = node->m_Next;
}
deleteNode(node->m_Next);
node->m_Next = NULL;
}
Here is an alternative approach using the fast and slow scan trick:
void split(NODE *src, NODE **p1, NODE **p2) {
NODE *last = src;
*p1 = *p2 = NULL;
if (src && src->m_Next) {
NODE *slow = src;
NODE *fast = src;
while (fast->m_Next && fast->m_Next->m_Next) {
slow = slow->m_Next;
fast = fast->m_Next->m_Next;
}
*p1 = src;
*p2 = slow->m_Next;
slow->m_Next = NULL;
last = fast->m_Next; // last will be non NULL if length is odd
fast->m_Next = NULL;
}
if (last) {
deleteNode(last); // drop the last node if required
}
}

How to dynamically populate Linked List with Fibonacci series

I have a linked list, which I wanted to populate up to a certain loop number. I have my code below is shows a Fibonacci series using a C Linked list.
Here is my code without any loop:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int count;
int fibo;
struct Node* next;
}node;
int
fibo(int val){
if(val == 1 || val == 2) {
return 1;
}
return fibo(val - 1) + fibo(val - 2);
}
int
main (void)
{
node f1, f2, f3;
f1.count = 1;
f1.fibo = fibo(1);
f2.count = 2;
f2.fibo = fibo(2);
f3.count = 3;
f3.fibo = fibo(3);
f1.next = &f2;
f2.next = &f3;
f3.next = NULL;
printf("f1 fibo : %i\n", f1.fibo);
printf("f2 fibo : %i\n", f2.fibo);
printf("f3 fibo : %i\n", f3.fibo);
return (0);
}
Now I want to do this via a loop. How would I do that?
For this answer, I'm going to ignore the computational efficiency concerns that arise from recomputing all of the Fibonacci numbers up to the given number you are retrieving with each call to fibo(n).
Linked lists are not usually "random access" data structures that let you access an arbitrary element with an index. When using a linked list with pointers, you only need to have the pointer to the head (first element) of the linked list. You then traverse the list starting at the head using a loop going through each next link. If a list is empty, your head is usually NULL.
You can apply this here. One way (there are several) is to define a function to allocate and set a single entry:
node *set_fibo(int n)
{
node *fibo_entry = malloc(sizeof(node));
if ( fibo_entry == NULL ) {
// error
}
fibo_entry->count = n;
fibo_entry->fibo = fibo(n);
fibo_entry->next = NULL;
return fibo_entry;
}
And then in your main:
node *fibo_list = NULL;
node *last_fibo = NULL;
// Assume n_fibo is the number of Fibonacci numbers you want to store in order
for ( int n = 1; n <= n_fibo; n++ ) {
if ( n == 1 )
fibo_list = last_fibo = set_fibo(1);
else {
last_fibo->next = set_fibo(n);
last_fibo = last_fibo->next;
}
}
Although the question has already been answered, I would like to add something regarding the efficiency aspect of your code. As pointed out before, you do not have to calculate the fibo value by starting from the beginning, since you saved the latest results in the singly linked list.
So given you have the following list 1-1-2-3-5-, you can easily calculate the fibo value of the new node by simply adding the fibo value of the two lates elements (i.e. 3 and 5). Hence the value of the fibo value of the new node should be 8.
Given the pointer to the second last element, this function will add add a new node to the list and set the correct fibo value:
void addNode(struct Node* node){
struct Node* n = malloc(sizeof(struct Node));
n->next = NULL;
n->count = node->next->count + 1;
n->fibo = node->fibo + node->next->fibo;
node->next->next = n;
}
In order to use this function, you have to create the first two nodes in the list:
struct Node* n2 = malloc(sizeof(struct Node));
n2->count = 2;
n2->fibo = 1;
n2->next = NULL;
struct Node* n1 = malloc(sizeof(struct Node));
n1->count = 1;
n1->fibo = 1;
n1->next = n2;
If you now want to add - lets say 10 - new nodes, you simply do:
struct Node* ptr = n1;
int i;
for(i=0; i<10;i++) {
addNode(ptr);
ptr = ptr->next;
}
If you now want to print the entries of all nodes in the list, simply iterate over the list until you reach NULL.
ptr = n1;
while(ptr != NULL) {
printf("fib(%d) = %d\n ", ptr->count, ptr->fibo);
ptr = ptr->next;
}
Please keep in mind, that you have to manually free dynamically allocated items!
In your example, the nodes are automatic variables in main. They are not dynamically allocated and they live as long as you don't return from main. You can extend this concept with a automatic array of nodes:
#include <stdio.h>
#include <stdlib.h
typedef struct Node Node;
struct Node {
int count;
int fibo;
Node* next;
};
#define N 30
int main (void)
{
Node fibo[N];
Node *head = NULL;
Node **p = &head;
int f1 = 0;
int f2 = 0;
for (size_t i = 0; i < N; i++) {
Node *nd = &fibo[i];
nd->count = i + 1;
nd->fibo = f2 + f1 ? f2 + f1 : 1;
f1 = f2;
f2 = nd->fibo;
*p = nd;
p = &(*p)->next;
}
*p = NULL;
Node *nd = head;
while (nd) {
printf("fib(%d) == %d\n", nd->count, nd->fibo);
nd = nd->next;
}
return (0);
}
It's not clear, though, why you need the Fibonacci series as linked list. Also, a word of warning: Don't mix nodes on the stack (like here) and nodes on the heap (as in lurker's answer) in a list. This answer just extends your answer to many nodes, whereas lurker's answer shows a more general concept of linked lists.
Here is how I think you can do it. You can use an array for the nodes.
node f[3];
int i;
for ( i = 0 ; i < 3 ; i++ )
{
f[i].count = i+1;
f[i].fibo = fibo (i+1);
if ( i == 2 )
{
f[i].next = NULL;
}
else
{
f[i].next = &f[i+1];
}
}

Swapping linked list items issue C

i'm trying to invert the "info" field of the in a list like the one below
struct nodo {
int info;
struct nodo *next;
struct nodo *prev;
} ;
typedef struct nodo nodo;
Here is the main, the two output should be the original list of n mebmers, and the inverted list (First value go n , second n-1 and so on)
int main(int argc, const char * argv[]) {
struct nodo *p;
p = CreateList();
PrintList(p);
IvertList(p);
Printlist(p);
return 0;
}
Here is InvertList(): (Count() function just returns dimension of the list, i know it is a messy way but i'm focused on result for now)
void InvertList (struct nodo *p) {
int tmp = 0, num = 0, i = 0;
num = (Count(p));
tmp = num;
for (i=1; i!=tmp; i++) {
Swap(p,num);
num--;
}
}
And here is Swap(), this should bring a value (int info) to the first place of the list, to the last swapping with each:
void Swap (struct nodo *p, int n) {
int *tmp1 = NULL, *tmp2 = NULL;
int i;
for ( i = 1; i != n && p != NULL; i++) {
tmp1 = &p->info;
p = p->succ;
tmp2 = &p->info;
p->info = *tmp1;
p->prec->info = *tmp2;
}
}
Now the output i got printed is:
Value: 1
Value: 2
Value: 3
Value: 4
Value: 5
Value: 1
Value: 1
Value: 1
Value: 1
Value: 1
Where the last 5 values should be 5-4-3-2-1.
The bug(s) in your code not withstanding, you're not reversing your physical list at all, which I can all-but-guarantee is the point of the exercise in the first place.
Inversion of a linked list means all the pointers switch directions and the old tail becomes the new head. You seem to be avoiding that and trying to swap node info values instead.
To invert your list using simple pointer swapping:
// note head pointer passed by address
void InvertList(node **pp)
{
node *cur = *pp;
while (cur)
{
node *tmp = cur->prev;
cur->prev = cur->next;
cur->next = tmp;
*pp = cur;
cur = cur->prev;
}
}
And invoke from main() as:
InvertList(&p);
Note that no info values need be swapped, copied, etc. The node pointers simply switch direction and their enumeration will start at the other end. A full working example appears below:
#include<stdio.h>
#include<stdlib.h>
struct node
{
int info;
struct node *next;
struct node *prev;
};
typedef struct node node;
static void PrintList(const node *head)
{
while (head)
{
printf("%d: this=%p, prev=%p, next=%p\n",
head->info, head, head->prev, head->next);
head = head->next;
}
}
static void InvertList(node **pp)
{
node *cur = *pp;
while (cur)
{
node *tmp = cur->prev;
cur->prev = cur->next;
cur->next = tmp;
*pp = cur;
cur = cur->prev;
}
}
int main()
{
node *prev = NULL, *head = NULL, **pp = &head;
for (int i=1; i<=5; ++i)
{
*pp = malloc(sizeof **pp);
(*pp)->info = i;
(*pp)->prev = prev;
prev = *pp;
pp = &(*pp)->next;
}
*pp = NULL;
PrintList(head); // prints 1,2,3,4,5
InvertList(&head);
PrintList(head); // prints 5,4,3,2,1
}
Output (addresses vary, obviously)
1: this=0x1001054b0, prev=0x0, next=0x1001054d0
2: this=0x1001054d0, prev=0x1001054b0, next=0x1001054f0
3: this=0x1001054f0, prev=0x1001054d0, next=0x100105510
4: this=0x100105510, prev=0x1001054f0, next=0x100105530
5: this=0x100105530, prev=0x100105510, next=0x0
5: this=0x100105530, prev=0x0, next=0x100105510
4: this=0x100105510, prev=0x100105530, next=0x1001054f0
3: this=0x1001054f0, prev=0x100105510, next=0x1001054d0
2: this=0x1001054d0, prev=0x1001054f0, next=0x1001054b0
1: this=0x1001054b0, prev=0x1001054d0, next=0x0
There is a bug in your Swap fcn:
p->info = *tmp1;
p->prev->info = *tmp2;
But what are tmp1 and tmp2 at that time? Well, after we advanced p, tmp1 points at p->prev->info, while tmp2 = &p->info; So we could rewrite these assignments in effect as:
p->info = p->prev->info;
p->prev->info = p->info;
So, we could rewrite them again, in effect, as:
p->info = p->prev->info;
p->prev->info = p->prev->info;
So, the second assignment doesn't change anything in effect. Therefore, the first call to Swap in InvertList takes the value of the first element (1) and sets all the values in the list equal to it. The subsequent calls to Swap act similarly but have no effect as the list already contains all 1's.
Here's a simple way to rewrite Swap:
void Swap(struct nodo *p, int n)
{
if (n <= 1)
return;
int tmp = p->info;
for (int i = 1; i != n; ++i, p = p->next)
p->info = p->next->info;
p->info = tmp;
}
Note, however, that the way you've written InvertList is doing theta(n^2) work. The first loop iteration shifts the first element n-1 spots, the second iteration shifts the first element n-2 spots, the third iteration shifts the first element n-3 spots, and so on, down to shifting the first element 1 spot. So, you end up doing something like n * (n - 1) / 2 total shifts to reverse the list.
A linked list can be reversed / inverted in theta(n) work. See if you can figure out a better way to do this. If you had a pointer to both the beginning and the end of the list (which you often want anyway), then you could do something similar to reversing the characters in a string, for example.

Printing deletes the value from my linked list

As a part of an assignment, I need to write two functions:
a function that sums up two natural numbers represented as a linked list
a functions that prints a number represented in the same way.
for some reason, both function work perfectly fine separately, but when I try to use the print function on the result of the sum function, it changes the value of the sum right in the beginning of the print function , and prints the wrong value. when I use printf to print the same value in the main, there is no problem. my code is detailed below. any ideas?
void main()
{
int a[1] = { 1 },
b[1] = { 2 };
int * *pa, **pb;
List lst1, lst2;
List sum;
pa = (int * *) malloc(sizeof(int * )); * pa = &a[0];
pb = (int * *) malloc(sizeof(int * )); * pb = &b[0];
lst1 = arrToList(pa, 1);
lst2 = arrToList(pb, 1);
addNumbers(lst1, lst2, &sum);
//printf("%d\n",*(sum.head->dataPtr));
printNumber(sum);
}
//a function that recieves a number represented ad a list and prints it
void printNumber(List num)
{
ListNode * curr;
int currData,
i,
number;
if (isEmptyList(num) == TRUE)
printf("the input was an empty list, nothing to print");
else
{
i = 0;
number = 0;
curr = num.head;
while (curr != NULL)
{
currData = *(curr - >dataPtr);
number = number + currData * ((int) pow(10, i));
curr = curr - >next;
i++;
}
printf("%d \n", number);
}
}
// a function that sums in list
// representation two numbers,
// each represented as a list
void addNumbers(List n1, List n2, List * sum)
{
ListNode * currN1;
ListNode * currN2;
ListNode * currSum;
int currN1N2Sum; //stores the sum of the current digits in n1 and n2
int carrier,
prevCarrier; //current and previous carriers that carries +1 to the
next digit of sum
if the lst sum was bigger then 9
if ((isEmptyList(n1) == TRUE) || (isEmptyList(n2) == TRUE))
printf("bad input =(");
else
{
currN1 = n1.head;
currN2 = n2.head; * sum = createEmptyList();
carrier = 0;
prevCarrier = 0;
while ((currN1 != NULL) && (currN2 != NULL))
{
currN1N2Sum = *(currN1->dataPtr) + *(currN2->dataPtr) + prevCarrier;
if (currN1N2Sum > 9)
{
carrier = 1;
currN1N2Sum = currN1N2Sum - 10;
}
currSum = creatNewListNode( & currN1N2Sum, NULL);
insertNodeToEnd(sum, currSum);
prevCarrier = carrier;
carrier = 0;
currN1 = currN1 - >next;
currN2 = currN2 - >next;
} //while ((currL1!=NULL)&&(currL2!=NULL))
while (currN1 != NULL)
{
currN1N2Sum = *(currN1 - >dataPtr) + prevCarrier;
currN1 = currN1 - >next;
if (prevCarrier != 0) prevCarrier = 0;
}
while (currN2 != NULL)
{
currN1N2Sum = *(currN2 - >dataPtr) + prevCarrier;
currN2 = currN2 - >next;
if (prevCarrier != 0) prevCarrier = 0;
}
} // ! ((isEmptyList(n1)==TRUE)||(isEmptyList(n2)==TRUE))
}
here is the rest of the code:
typedef struct listNode{
int* dataPtr;
struct listNode* next;
} ListNode;
typedef struct list
{
ListNode* head;
ListNode* tail;
} List;
List createEmptyList()//creates and returns an empty linked list
{
List res;
res.head = res.tail = NULL;
return res;
}
Bool isEmptyList ( List lst )//checks if a given list is empty or not
{
if (lst.head == NULL && lst.tail == NULL)
return TRUE;
else
return FALSE;
}
void insertDataToEnd ( List * lst, int *dataPtr ) //inserts new data to the end of an existing linked list
{
ListNode * newTail;
newTail = creatNewListNode ( dataPtr, NULL );
insertNodeToEnd(lst,newTail);
}
void insertNodeToEnd ( List * lst, ListNode * newTail )//insert an existing node to an existing linked list
{
if (isEmptyList(*lst) == TRUE )
insertNodeToStart ( lst,newTail );
else
{
(*lst).tail -> next = newTail;
newTail->next = NULL;
(*lst).tail = newTail;
}
}
ListNode * creatNewListNode ( int * dataPtr, ListNode * next )//inserts new node in an existing linked list
{
ListNode * res;
res = (ListNode *) malloc (sizeof(ListNode));
res -> dataPtr = dataPtr;
res -> next = next;
return res;
}
void insertNodeToStart ( List * lst, ListNode * newHead )//inserts node to the begining of a given linked list
{
if ( isEmptyList( *lst ) == TRUE )
{
(*lst).head = newHead;
(*lst).tail = newHead;
newHead -> next = NULL;
}
else
{
newHead -> next = (*lst).head;
(*lst).head = newHead;
}
}
The bug is in the function addNumbers.
When you add a node to store the sum you pass a pointer to the variable currN1N2Sum which is a local variable (stored on the stack). When the addNumbers function terminates, the storage of the local variable is set free. The value found at that location will remain unchanged and thus apparently valid as long as the storage is not reused.
This is why you had the impression the addNumbers function was correct. When calling the printNumber function the storage is overwritten and you find a different value in there.
This explain your bug.
There is another problem with addNumbers. When you will try to add two digit numbers, the content of the currN1N2Sum will be overwritten by a new value.
What you should do is allocate a buffer (malloc) and store the value contained into currN1N2Sum into it. Pass the pointer to the buffer into the new node.
BTW: you may change (*lst).head in lst->head. It will make your code more readable.
We need to see some more code: how you define the data structure for holding nodes, how you add nodes etc.
The following line is suspect:
number=number+currData*((int)pow(10,i));
Say, you have 123 stored as 1, 2, and 3 nodes:
number = 0;
number = 0 + 1 * 1 = 1;
number = 1 + 2 * 10 = 21;
number = 21 + 3 * 100 = 321;
But if you store is as 3, 2, and 1 nodes you'd get:
number = 0;
number = 0 + 3 * 1 = 3;
number = 3 + 2 * 10 = 23;
number = 23 + 1 * 100 = 123;
Is this your problem?
I'm not if this is an issue or not without seeing the implementation of createNewListNode(), but here's something to think about:
Where are the dataPtrs in the sum list pointing after you return from the addNumbers() call?
You've got a problem with createEmptyList. you declare there a list called res and return the structure but the minute this function returns that structure is not valid any more.
try using malloc (for the struct) and then return the pointer to the caller. You use this function in the beginning with *sum.
This is a similar bug to what chmike found so you better fix both.
I think you might be messing things up pointer-wise... The way you're allocating the list 'sum' in addNumbers seems very, very odd. (And I would not be surprised if it's breaking things...)
Try making these changes:
In main:
List *sum;
<...>
addNumbers(lst1,lst2,sum); //Note the absence of the reference operator &
printNumbers(*sum);
(Alternatively, change printNumbers to accept a (List *) instead of (List)).
Hope this helped XD
EDIT:
Try allocating 'sum' before making calls to addNumbers().
lst1 = arrToList(pa, 1);
lst2 = arrToList(pb, 1);
sum = createEmptyList();
I still think the way that your data structures are a little weird :S

Resources