This function does not return the intended result (swapping a and b).
#include<stdio.h>
#include<stdlib.h>
void swap_one(int *x, int *y) {
int *tmp;
tmp = x;
x = y;
y = tmp;
printf("x = %d y = %d\n", *x, *y);
}
void swap_two(int *x, int *y) {
}
int main() {
int a = 5;
int b = 100;
printf("Before a = %d b = %d\n\n", a, b);
int *p = (int *) malloc(sizeof(int));
int *q = (int *) malloc(sizeof(int));
p = &a;
q = &b;
swap_one(p, q);
printf("After a = %d b = %d\n", a, b);
return 0;
}
But the below code works as expected.
#include <stdlib.h>
#include <stdio.h>
typedef struct ListElmt_ {
void *data;
struct ListElmt_ *next;
} ListElmt;
typedef struct List_ {
int size;
int (*match) (const void *key1, const void *key2);
void (*destroy) (void *data);
ListElmt *head;
ListElmt *tail;
} List;
void list_init (List *list) {
list->size = 0;
list->match = NULL;
list->destroy = NULL;
list->head = NULL;
list->tail = NULL;
}
int list_ins_next(List *list, ListElmt *element, void *data) {
ListElmt *new_element;
/* Alocate storage for the element. */
if ((new_element = (ListElmt *) malloc(sizeof(ListElmt))) == NULL) return -1;
/* new_element->data is of type void *. So we use (void *) data */
new_element->data = (void *)data;
if (element == NULL) {
/* Handle insertion at the head of the list */
if (list->size == 0) list->tail = new_element;
new_element->next = list->head;
list->head = new_element;
} else {
if (element->next == NULL) list->tail = new_element;
new_element->next = element->next;
element->next = new_element;
}
list->size++;
return 0;
}
/* Print the list */
static void print_list(const List *list) {
ListElmt *element;
int *data;
int i;
/* Display the linked list */
fprintf(stdout, "List size is %d\n", list->size);
i = 0;
element = list->head;
while (1) {
data = element->data;
fprintf(stdout, "list[%03d] = %03d\n", i, *data);
i++;
if (element->next == NULL) {
break;
} else {
element = element->next;
}
}
}
int main(int argc, char **argv) {
List list;
ListElmt *element;
int *data;
int i;
/* list = (List *) malloc(sizeof(List)); */
/* Initialize the linked list */
List *listPtr;
listPtr = &list;
list_init(listPtr);
/* Perform some linked list operations */
element = listPtr->head;
for (i = 10; i > 0; i--) {
if ( (data = (int *) malloc(sizeof(int))) == NULL) return 1;
*data = i;
if (list_ins_next(listPtr, NULL, data) != 0) return 1;
}
print_list(listPtr);
fprintf(stdout, "Value in *data is:%d\n", *data);
return 0;
}
Question is: In the swap_one function, x=y is similar to new_element->next = element->next or element->next = new_element. Why do new_element->next = element->next and element->next = new_element work but x =y in the swap_one function does not swap a and b?
Sorry for lot of the code but I am genuinely confused about this one.
Thanks.
The pointers are passed by value. Swapping the pointer values held in those variables does not achieve a swap of the data they point to.
Imagine that
&pis the address 0x1000 and&qis the address 0x1004.Now, you call
swap_one(&p, &q);-- the value of the pointerxis 0x1000 and the value of the pointeryis 0x1004.You now swap the pointer values.
xis now 0x1004 which points atqandyis now 0x1000 which points atp. However,pandqnever moved in memory. You only changed the values stored in your pointers.When the function returns, those pointers go out of scope.
pandqstill hold the same contents as before, because you never modified them in the first place.So, to swap the values they point at, you must dereference the pointer to get at the actual data.
Contrast this to your linked list example. In that example, you had a pointer to a structure, and you were modifying its
nextmember. This actually modifies the pointer in memory, because that's where your linked list resides and how it stores values.However, the same issue would occur if you gave these pointers to some hypothetical function:
swap_next(node **x, node **y);--xandyare just local variables pointing at a pointer value. If you swap them, they do not modify anything other than themselves. So the same fix applies: to change data being pointed at, you must follow the pointer.