Why is my list->next pointer affected by free()? - c

I'm trying to implement a linked list and adding nodes to it. I encountered the following problem, when I try to free the pointer n after setting list->next to point to the same address of n, the int value inside the second node also changes to garbage value when I print it again. I want to know if inside the memory, n and list->next is stored as two separate pointers that hold the same value or it is stored as a single pointer? And if they were distinct, then why freeing n also affect list->next? Furthermore if freeing n make the second node became lost, then why I can still use the list->next->next pointer to add a third node, was list->next->next pointer also some random value that points to a random usable location ? Here is my code, sorry if my question is too vague, I'm trying my best to understand all this pointers.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
typedef struct node {
int number;
struct node *next;
} node;
int main(void) {
node a;
a.number = 1;
a.next = NULL;
node *list = NULL;
list = &a; // the first node
printf("%i \n", a.number);
node *n = malloc(sizeof(node)); // creating pointer to the second node
if (n != NULL) {
n->number = 2;
n->next = NULL;
}
list->next = n; // add the node to the list
printf("%p \n%p \n", n, list->next); // print out the address and value
printf("%i \n", list->next->number);
free(n);
printf("%p \n%p \n", n, list->next); // print out the address and value
printf("%i \n", list->next->number);
n = malloc(sizeof(node));
printf("%p \n%p \n", n, list->next);
if (n != NULL) {
n->number = 3;
n->next = NULL;
}
list->next->next = n;
printf("%i\n", (*(*(*list).next).next).number);
return 0;
}
Here is the output
1
0x5562319d62a0
0x5562319d62a0
2
0x5562319d62a0
0x5562319d62a0
1445140950
0x5562319d62a0
0x5562319d62a0
3

The assignment
list->next = n
doesn't copy the allocated memory. It just add another pointer pointing to the same memory.
If we "draw" it, before the assignment it looks something like this:
+---+ +-----------------+
| n | ---> | memory for node |
+---+ +-----------------+
Then after the assignment you have:
+---+
| n | -----------\
+---+ | +-----------------+
>--> | memory for node |
+------------+ | +-----------------+
| list->next | --/
+------------+
Then you pass n to free leading to this situation:
+---+
| n | -----------\
+---+ |
>--> ???
+------------+ |
| list->next | --/
+------------+
After the call to free, the pointer list->next is invalid. Any attempt to dereference it will lead to undefined behavior.

Related

How to delete a node in a linked list in c [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
what i need to do is to implement a function in c for deleting a node in a linked list, using a for and while loop with strcmp. The program compiles fine but the loop never stop, any suggestion on how to make it better?
The structure is this:
struct Test
{
char name[16];
int id;
};
typedef struct Node
{
struct Test structure;
struct Node * next;
}TNode;
typedef TNode * Nodo;
And the function i wrote is this:
void Delete(Nodo * pp)
{
Nodo i;
char temp[16], name[16];
printf("Insert the name to delete:");
scanf(" %s", name);
for(i = *pp; i->next != NULL ; i = i->next)
{
if(strcmp(i->structure.name, name) == 0)
{
while(i->next != NULL)
{
strcpy(temp,i->structure.name);
strcpy(i->structure.name, i->next->structure.name);
strcpy(i->next->structure.name, temp);
i = i->next;
}
}
}
}
UPDATE: The working function is this, thanks to Some programmer dude for the explanation:
void Delete(Nodo * pp)
{
Nodo i, prev;
char name[16];
printf("Insert the name to delete:");
scanf(" %s", name);
//case for the first node
if(strcmp((*pp)->structure.name, name) == 0)
{
Nodo old = *pp;
*pp = (*pp)->next;
free(old);
return;
}
//loop to delete node inside list
for(prev = *pp, i = prev->next; i != NULL ; prev = i, i = i->next)
{
if(strcmp(i->structure.name, name) == 0)
{
prev->next = i->next;
free(i);
break;
}
}
}
[Note: This doesn't actually answer the question, but it tells how to unlink nodes in a single-linked list, which IMO is the bigger problem the OP have.]
Lets say you have the following list
+---+ +---+ +---+ +---+
| A | -> | B | -> | c | -> | D |
+---+ +---+ +---+ +---+
If you want to remove node B then you don't copy the contents of the remaining list. Because that would give you the follow list:
+---+ +---+ +---+ +---+
| A | -> | C | -> | D | -> | D |
+---+ +---+ +---+ +---+
And that's not correct.
Instead you make the A node's next pointer point to C instead, so now the list becomes
+---+ +---+ +---+ +---+
| A | -\ | B | /-> | c | -> | D |
+---+ | +---+ | +---+ +---+
\-------/
Then you just free the node B, and you end up with
+---+ +---+ +---+
| A | -> | c | -> | D |
+---+ +---+ +---+
The trick to unlinking the node is to keep track of the previous node. It could be implemented something like this:
// Special case: Removing the first node in the list
if (strcmp((*pp)->structure.name, name) == 0)
{
TNode *old = *pp; // Save a pointer to the node that should be removed
*pp = (*pp)->next; // Actually unlink the node from the list
free(old); // Free the memory of the old node
return;
}
TNode *prev; // To keep track of previous node
TNode *curr; // The "current" node
for (prev = *pp, curr = prev->next; curr != NULL; prev = curr, curr = curr->next)
{
if (strcmp(curr->structure.name, name) == 0)
{
// Found the node to remove
prev->next = curr->next; // Unlink the current node from the list
free(curr); // Free the node
break; // No need to iterate anymore
}
}
The "special case" of the first node being removed could also be solved inside the loop, by initializing prev to NULL, and start curr with *pp instead. Then you need to check if prev is NULL or not inside the if in the loop.
The code might look like more, and it might be more lines (even after removing some or all of the empty lines), but I think most people would say it's easier to follow and see what's going on.
Of course, you also need to add a check for an empty list and that pp itself is not null (like pp != NULL && *pp != NULL).

Using fgets to read lines from a file into Binary Search Tree

Currently i'm trying to store each separate line in my file into a string, and then store it in a binary search tree, but a problem occurs. For some reason when I print my BST only the last line is outputted and not the first 3. Below is my code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
int count;
char* key;
struct node* left;
struct node* right;
};
struct node *newNode(char* item)
{
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->key = item;
temp->left = NULL;
temp->right = NULL;
temp->count = 1;
return temp;
};
void printInorder(struct node* root)
{
if(root != NULL)
{
printInorder(root->left);
printf("%s \n", root->key);
printInorder(root->right);
}
}
struct node* insert(struct node* node, char* key)
{
if(node == NULL)//When tree is empty
return newNode(key);
if(strcmp(key, node->key) < 0)
node->left = insert(node->left, key);
if(strcmp(key, node->key) > 0)
node->right = insert(node->right, key);
return node;
};
int main()
{
struct node *root = NULL;
int i = 0;
char str[100];
FILE* fp;
fp = fopen("textFile.txt", "r");
if ((fp = fopen("textFile.txt","r")) == NULL)
{
printf("Could not open textFile.txt\n");
exit(1);
}
while(fgets(str, 100, fp) != NULL)
{
++i;
root = insert(root, str);
printf("%3d: %s", i, str);
}
printf("bst printed\n");
printInorder(root);
return 0;
}
textFile.txt contains
bob is working.
david is a new hire.
alice is bob's boss.
charles doesn't like bob.
And when the bst is printed the only line that is outputted is the last one
Charles doesn't like bob.
Any help would really be appreciated.
Notice that when you create a node with newNode, you store a copy of the pointer passed into it, rather than a copy of the string being pointed at. This means that every time you insert a value into the tree, it stores a pointer to the str buffer in main. In other words, after you do your first insertion, things look like this:
+------------+
| BST Node | str
+------------+ +---+---+---+---+---+...+---+
| key | ---------> | b | o | b | | i | | 0 |
+------------+ +---+---+---+---+---+...+---+
When you then read the next line of the file, you're overwriting str with the contents of that line, so the picture looks like this:
+------------+
| BST Node | str
+------------+ +---+---+---+---+---+...+---+
| key | ---------> | d | a | v | i | d | | 0 |
+------------+ +---+---+---+---+---+...+---+
Notice that your BST now acts as though it contains "david is a new hire" even though you never inserted that value. As a result, when you try inserting "david is a new hire" into the BST, nothing happens.
The same thing happens for the next few reads, until eventually you read the final line of the file, when things look like this:
+------------+
| BST Node | str
+------------+ +---+---+---+---+---+...+---+
| key | ---------> | c | h | a | r | l | | 0 |
+------------+ +---+---+---+---+---+...+---+
This is why you're only seeing the line about Charlie at the end - the BST is directing you to the single shared copy of the buffer.
To fix this, make your BST store copies of the strings passed into it, or copy the strings before storing them in the tree. For example, you might have the newNode function call strdup to get its own copy of the string to store:
struct node *newNode(char* item)
{
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->key = strdup(item); // <--- here!
/* TODO: Error-handling! */
temp->left = NULL;
temp->right = NULL;
temp->count = 1;
return temp;
};
That should fix your issue. Just make sure to deallocate everything when you're done!

Storing an array of structs in a linked list

I have an array of struts called arrayOfElements , each element being a struct called Element
typedef struct {
void* data;
} Element;
data is a void pointer as I dont know in advanced what type of variable will be stored
I've malloc'd this array to have 4 elements ( this is done by user input but ive hard coded 4 for this question)
Element* arrayOfElements;
arrayOfElements= malloc(4 * sizeof(Element));
Now to this point I can store strings and ints in arrayOfElements
Store Int
arrayOfElements[0].data = malloc( sizeof(int) );
int *ptr = arrayOfElements[0].data;
*ptr = 65;
Store String
arrayOfElements[0].data = malloc( strlen(str) + 1 );
strcpy( arrayOfElements[0].data, str );
And that all works. My Issue is how do I got about making a linked List and making each element store an instance of arrayOfElements
so far my linked list is
typedef struct LinkedListNode {
void** ElementArray;
struct LinkedListNode* next;
} LinkedListNode;
typedef struct {
LinkedListNode* head;
} LinkedList;
so the void** ElementArray will point to each arrayOfElements
void insert(LinkedList* head, Element inArrayOfElements)
{
LinkedListNode insertNode;
/* Points ElementArray to inArrayOfElements */
HOW DO I DO THIS AS ElementArray is a void**
/* Points next to the head */
(*insertNode).next = head;
/* Re-points head to new head of Linked List */
head = insertNode;
}
My Goal is to have something like this
LINKEDLIST
+---+ +---+---+----+
| | -> | | | | arrayofElements
+---+ +---+---+----+ +---+---+----+
| | -------------------> | | | |
+---+ +---+---+----+ +---+---+----+
| | -> | | | |
+---+ +---+---+----+ +---+---+----+
| | -------------------> | | | |
+---+ +---+---+----+
Question / TL;DR
My question is how do I make void** ElementArray (in the linked list) point to arrayOfElements.
If I understand your question correct, there is no need for double pointers. Just do:
typedef struct LinkedListNode {
Element* data;
struct LinkedListNode* next;
} LinkedListNode;
LinkedListNode* insert(LinkedListNode* head, Element* inArrayOfElements)
{
LinkedListNode* insertNode = malloc(sizeof(LinkedListNode));
insertNode->next = head;
insertNode->data = inArrayOfElements;
return insertNode;
}
Use it like:
head = insert(head, someArrayOfElements);
Note: The real code should check for NULL pointers but I omitted that for simplicity.

How to access values from pointers to pointers in C?

I am writing a program that is attempting to implement a hash table in C. It has to use a pointer to a pointer as an attribute in a struct data type. Here is the code of the relevant structs.
struct node {
char * data;
struct node * next;
};
struct hashtable {
int size;
struct node ** table;
};
Part one of question:
I have been doing a lot of research to figure out just how pointers to pointers work but I still can't seem to get my head around it. Every example I've found assigns two different pointer names to the first and second pointer. eg
x = 5;
*p = &x;
**q = &p;
What about the case above "struct node ** table;"
Is ** table the same as **q in this case?
What would the values of q , *q and **q be in this case? is q = 5 and then *q and **q work back through the addresses or is **q = 5 and *q and q store the addresses?
Part two of question:
How do I access a pointer to a pointer within another function? Here is the code I have right now.
struct hashtable * hashtable_new(int size){
struct hashtable *newTable;
if ( size < 1 )
{
return NULL;
printf("Its returning Null.");
}
else
{
newTable = malloc(sizeof(struct hashtable));
newTable -> size = size;
newTable -> table = malloc(sizeof(struct node) * size);
int i;
for (i = 0; i < size; i++ )
{
newTable -> table[i] = NULL;
}
fprintf(stderr, "Table has been created.");
return newTable;
}
};
I'm not sure I understand how to access either the pointer or the pointer to a pointer through the -> symbol. Is it "newtable -> table" or "newtable -> -> table" ?
The aim of the table is essentially to be a 2d table, where the list is primarily 1D and can spread to 2D to deal with collisions in the hashing.
End note:
Hopefully I've provided enough information to make contextual sense asking this question. Its my first time asking a question on stackoverflow so feel free to ask me extra question, provide CC or flag any mistakes I've made asking this question.
Thank you!
There are several ways to look at a pointer to a pointer. One way is as you described with
int x = 5;
int *p = &x;
int **q = &p;
After all that, the following are all true:
**q == *p == x == 5
*q == p == &x
q == &p
However, another way to look at a pointer to a pointer is as an array of pointers. For example, assume the declaration:
int *arr[10];
Except when it is the operand of the sizeof or unary & operands, the expression arr will be converted ("decay") from type "10-element array of int *" to "pointer to int *", or int **.
If you want to dynamically allocate an N-element array of pointers to struct node, you would write
struct node **arr = malloc( sizeof *arr * N );
You would use the [] subscript operator to access elements in arr as you would a normal array. Since arr has type struct node **, each arr[i] has type struct node *, so you would access members of the structure like so:
arr[i]->data = "foo"; // use -> when the LHS is a pointer to a struct or union
arr[i]->next = NULL;
struct hashtable allows you to create multiple hashtable instances, each one of which has a size member and an array of struct node * which you allocate at runtime, like so:
struct hashtable h1;
h1.size = 512;
h1.table = calloc( h1.size, sizeof h1.table ); // calloc initializes all elements of
// h1.table to NULL
if ( !h1.table )
{
// calloc call failed, handle as appropriate
}
You'd insert a new element into the table like so:
/**
* Assumes we know that the string data points to is not already in
* the table. hashfunc is a pointer to the hashing function.
*/
void insert( struct hashtable *h, const char *data, size_t (*hashfunc)(const char *))
{
/**
* Create a new table entry. Remember that table is an array of
* *pointers* to struct node, and that each array element is initially
* NULL. We still need to allocate something for that table entry
* to point *to*.
*/
struct node *newNode = malloc( sizeof *newNode );
if ( !newNode )
{
/**
* Memory allocation for new node failed, handle as appropriate
*/
}
newNode->data = malloc( strlen( data ) + 1 );
strcpy( newNode->data, data );
/**
* Get the table index by computing the hash and modding against the
* table size.
*/
size_t idx = hashfunc( data ) % h->size;
/**
* Insert newNode at the head of the list starting at
* h->table[idx]. In reality you'd probably want to insert
* strings in order, but for a toy example this is good enough.
*/
newNode->next = h->table[idx]; // newNode->next points to the previous head of list
h->table[idx] = newNode; // newNode becomes new head of list.
}
When you're done, your hashtable looks something like this:
+---+
h1: | | size
+---+ +---+ +---+---+ +---+---+
| | table ----> | | --> | | | --> | | |
+---+ +---+ +---+---+ +---+---+
| |
+---+ +---+---+
| | --> | | |
+---+ +---+---+ +---+---+ +---+---+
| | --> | | | --> | | | --> | | |
+---+ +---+---+ +---+---+ +---+---+
...
table points to an array of struct node *, each of which may point to an instance of struct node, each of which may point to another instance of struct node. In the picture above, two strings have hashed to table[0],
one to table[2], and three to table[3].
Here's a little program that might help you, it might be worth playing about with pointers for a bit and inspecting them, output addresses etc.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
char *p1 = "String of text.";
char **p2;
/**
* We can print the avtual address of *p1 and **p2...
*/
fprintf(stdout, "p1 = %p\n", p1);
fprintf(stdout, "p2 = %p\n", p2);
/**
* Now if we point p2 at p1 we can then check what address
* *p2 points at...
*/
p2 = &p1;
fprintf(stdout, "*p2 = %p\n", *p2);
/**
* So if you think about it, *p2 should be the same at p1
* if we print it as a string:
*/
fprintf(stdout, "p1 is %s\n*p2 is %s\n", p1, *p2);
exit(EXIT_FAILURE);
}
Hope this helps.
As for referencing the struct from another function, if you're passing a pointer to that structure you use a single -> to refer to any member of the struct...but you are allocating another struct within your struct - using a pointer.
Say I have
struct one {
char *string;
}
struct two {
struct *one a;
struct one b;
char *whatever;
}
If have a pointer to a struct two:
struct two *t;
And it had its member a allocated a struct one...then I'd reference the members of a using ->
t -> a -> string;
But b isn't a pointer so you would do:
t -> b.string;

Swap nodes in a singly-linked list

I am trying to swap two nodes. For example if the nodes are a and b I am passing the pointers
(a-1)->next and (b-1)->next which are basically nodes a and b.
void swap(struct stack **a,struct stack **b)
{
struct stack *temp1 = *a, *temp2 = *b, *temp3 = *b;
*a = *b;
(*b)->next = (temp1)->next;
temp2 = temp1;
(temp2)->next = temp3->next;
}
What am I doing wrong? When I am trying to print the nodes after calling the function it's an infinite loop. Please help.
Why Infinite loop?
Infinite loop is because of self loop in your list after calling swap() function. In swap() code following statement is buggy.
(*b)->next = (temp1)->next;
Why?: Because after the assignment statement in swap() function temp1's next starts pointing to b node. And node[b]'s next point to itself in a loop. And the self loop is reason for infinite loop, somewhere in your code where you traverse linked list.
Below I drawn to show how swap() works step-by-step. May be this help you to understand your error:
You didn't mention but I am assuming linked list having following relation between a and b: (read red comments)
(step-1):
+----+----+----+ +---+----+----+
| one |----->| two |
+----+----+----+ +---+---+-----+
^ ^ ^ ^
| | | |
| *a | *b
| |
temp1 temp2, temp3 "after assignment to temp variables"
(step-2): ^
|
*a = *b | *a "<--- next step"
(step-3): The buggy statement
(*b)->next = (temp1)->next; "Change link: (temp1)->next; is `two` node"
" *b is `two`, So Self loop"
+----+----+----+ +---+----+----+ <---|
| one | | two |-----|
+----+----+----+ +---+---+-----+
^ ^ ^ ^
| | | |
| | *b *a
| |
temp1 temp2, temp3 " after assignment to temp"
See (temp1)->next; is actually b and you are assigning (*b)->next = (*b) by doing (*b)->next = (temp1)->next; hence adding a self loop.
(step-4):
I think with the diagram you can easily understand what last two lines of your swap() code are doing:
temp2 = temp1;
(temp2)->next = temp3->next;
Following is my diagram for this two lines:
temp2 = temp1;
+----+----+----+ +---+----+----+ <---|
| one | | two |-----| "<--- Self loop"
+----+----+----+ +---+---+-----+
^ ^ ^ ^
| | | |
| | *b *a
| |
temp2 = temp1; temp3
(step-5): Even last line of your function swap() left loop as below:
(temp2)->next = temp3->next; " last line of your code"
+----+----+----+ +---+----+----+ <---|
| one |----->| two |-----| "<-- Self loop"
+----+----+----+ +---+---+-----+
^ ^ ^ ^
| | | |
| | *b *a
| |
temp2 = temp1; temp3
So loop still there at two node so infinite loop.
How to swap two nodes in single linked list?
One way is swap node's data instead of swapping node's position it self in linked list (as I commented to your question). But you wants to swap node's position in list.
Well this good! if node data size is larger, that time its better to swap node's position rather then swap node's data(swapping data will be bad choice)
Because you having single linked list, to swap any two arbitrary nodes in list you need there previous node addresses too. (this is the point you don't consider in your swapping logic)
WHY need previous pointers?:
Suppose after some successful insert(push) operations, your list becomes as follows:
0 <--------TOP - "head"
9 <--p
2
6 <--q
5
A horizontal diagram- Suppose you want to swap say two nodes (q) and (p):
+---+ +---+ +---+ +---+ +---+
| 0 |--->| 9 |--->| 2 |--->| 6 |--->| 5 |---
+---+ +---+ +---+ +---+ +---+ |
^ ^ ^ null
| | |
| (q) (p)
(head)
As I said, to swap we need previous pointers. You need to think about following
(In theory, I am writing for specific nodes (p) and (q) just to keep explanation simple. but my implementation is quit general):
In list previous pointers:
node[0] points to node[9] that is (q), and
node[2] points to node[6] that is (p)
And
node[9] points to node[2]
node[6] points to node[5]
NOTICE: If you want to swap two nodes say node[ 9 ] and node[ 6 ] then you should use pointers of the nodes previous to these two nodes.
For example: two swap node[ 9 ] and [ 6 ], you also need to change next pointer of node[ 0 ] and next pointer of node[ 2 ] in above diagram.
How would be the list after swapping this two nodes?
+---+ +---+ +---+ +---+ +---+
| 0 |--->| 6 |--->| 2 |--->| 9 |--->| 5 |---
+---+ +---+ +---+ +---+ +---+ |
^ ^ ^ null
| | |
| (p) (q)
(head)
What is now in previous nodes [o] and [2]?
After swapping, In list previous pointers
node[0] points to node[6] that is (q), and
node[2] points to node[9] that is (p)
And
node[9] points to node[5]
node[6] points to node[2]
So if you want to swap two nodes; there immediate previous node also effects and because list is single link list you need previous pointers too.
How to find previous node pointers?
Suppose you want to swap any two nodes node[p] and node[q] then you can use head pointer to find previous node.
So swap function syntax (In my implementation) is like:
void swap(struct stack **head, // head node
struct stack **a, // first candidate node to swap
struct stack **b); // first candidate node to swap
And you will call function like:
swap(&head, &p, &q);
Definition: (To understand code please read comments I added at almost each line)
void swap(struct stack **head,
struct stack **a,
struct stack **b){
// first check if a agrgument is null
if( (*head) == NULL || // Empty list
(*a) == NULL || (*b) == NULL){ // one node is null
// Nothing to swap, just return
printf("\n Nothing to swap, just return \n");
return;
}
// find previos nodes
struct stack* pre_a = get_prevnd(*head, *a);
struct stack* pre_b = get_prevnd(*head, *b);
//Now swap previous node's next
if(pre_a) pre_a->next = (*b); // a's previous become b's previous, and
if(pre_b) pre_b->next = (*a); // b's previous become a's previous
//Now swap next fiels of candidate nodes
struct stack* temp = NULL;
temp = (*a)->next;
(*a)->next = (*b)->next;
(*b)->next = temp;
//change head: if any node was a head
if((*head)==(*a))
*head = *b;
else
if((*head)==(*b))
*head = *a;
}
In swap() function you can notice that I call a helper function get_prevnd(, );. This function returns address of previous node in list. In The function get_prevnd(, );, first argument is list head and second argument is node for which you are looking for.
// find previous node function()
struct stack* get_prevnd(
struct stack* head,
struct stack* a
){
if(head == a){
// node[a] is first node
return NULL;
}
struct stack* temp = head; // temp is current node
struct stack* pre_a = NULL;
while(temp && temp!=a){ //search while not reach to end or the node
pre_a = temp; // find previous node
temp = temp->next;
}
if(temp!=a){// node[a] not present in list
fprintf(stderr, "\n error: node not found!\n");
exit(EXIT_FAILURE); // bad technique to exit()
}
return pre_a;
}
And fortunately the code is WORKING :). Below is link for online test of this code. I have tested for various kind of inputs.
CodePad: To Swap node in single linked list. Please check output.
And sorry for bad English
I was hoping for cut-and-paste code, but didn't find it. If anyone is still interested, this is the answer. I did the brute force analysis of all 3 cases.
// swaps nodes at locations *sp and *tp
struct stack *s = *sp; // store locations to prevent overwritten bugs
struct stack *t = *tp;
if(&t->next == sp) { // order u (tp)-> t (sp)-> s -> ...
t->next = s->next;
s->next = t;
*tp = s;
} else if(&s->next == tp) { // order u (sp)-> s (tp)-> t -> ...
s->next = t->next;
t->next = s;
*sp = t;
} else { // disconnected u (sp)->s -> ..., v (tp)->t -> ...
struct stack *next = s->next;
s->next = t->next;
t->next = next;
*sp = t;
*tp = s;
}
// If you track the end of your list, it be the one pointing to NULL.
if(s->next == NULL) {
end = &s->next;
} else if(t->next == NULL) {
end = &t->next;
}
Note: This code works if sp == tp, but assumes you don't have the pathological case where BOTH &s->next == tp && &t->next == sp (starting with cycle).
"KING KHAN"
SwapanyTwoNodeData(int, int); this function take two integer as parameter and swap these
node data.
1->2->6->3->4->5
SwapanyTwoNodeData (2,4);
1->3->6->2->4->5
100% Working Function. . . . Enjoy.
void Swap_Any_Two_Locations_data(int x,int x1){
if(head!=NULL){
int count=1,count1=1;
Node *temp,*temp1;
temp=head;
temp1=head;
while(temp->next!=NULL && count!=x ){
temp=temp->next;
count++;
}
while(temp1->next!=NULL && count1!=x1){
temp1=temp1->next;
count1++;
}
if(count==x && count1==x1){
int z=0;
z=temp->info;
temp->info=temp1->info;
temp1->info=z;
cout<<"Data Swapped"<<endl;
}
}
}

Resources