c++ - How to change LinkedList head pointer globally and not locally -
i have 2 implementations of this.
why particular implementation not work? have pointer pointer , im changing inside point doesn't retain change in main function
#include <iostream> using namespace std; struct node { int value = 4; node* next; }; void insertfront(node*, node**); int main(){ node head; head.value = 32; head.next = nullptr; node** headptr = new node*; (*headptr) = new node; *(*headptr) = head; (*headptr)->value = 32;//redundant, know (*headptr)->next = nullptr;//redundant, know cout << head.value << endl; insertfront(new node, headptr); cout << head.value << endl; system("pause"); return 0; } void insertfront(node* newhead, node** head2){ cout << "inside before swap " << (*head2)->value << endl; newhead->next = *head2; *head2 = newhead; cout << "inside after swap " << (*head2)->value << endl; }
why 1 work? can please explain in detail pointer magic going on? have vague idea im still little bit confused. understand using pointer head pointer allows change head address globally it's still little bit cloudy. can please clarify, going on these pointers in both implementation?
#include <iostream> using namespace std; struct node { int value = 4; node* next; }; void insertfront(node*, node**); int main(){ node** head = new node*; (*head) = new node; (*head)->value = 32; (*head)->next = nullptr; cout << (*head)->value << endl; insertfront(new node, head); cout << (*head)->value << endl; system("pause"); return 0; } void insertfront(node* newhead, node** head2){ cout << "inside before swap " << (*head2)->value << endl; newhead->next = *head2; *head2 = newhead; cout << "inside after swap " << (*head2)->value << endl; }
both implementations using double-indirection wrong, , both leak memory. you're question seems more double-indirection works , doesn't (whether realize or not). c question, , though applicable in c++, less language because reference parameters make easier (arguably).
i "use references pointers" (which do), saying "why doesn't car work?" , me answering "because car on here work". provide c answer (much dismay of own common sense, can feel furnaces firing flamethrowers sent way). if have time, include c++ answer (using references), no guarantees on that.
pointers pointers no different other pointer type. pointer types types who's variables defined "point" of type (i know, repetitive , trivial, bear me here). trivial example:
void foo(int x) { x = 5; }
obviously doesn't change x
on caller side, , seem keenly aware of that. if want change in/out parameter using pointers, need declare formal parameter pointer-to type, dereference said-pointer parameter within function body, , pass address caller. ie.
void foo(int *p) { *p = 5; } int main() { int x = 0; foo(&x); }
the truth parameters pass-by-value in c, even pointer parameters. yeah, read again. what? seriously. true. happens "value" you're passing address rather value within variable, , in being such, receiver must prepared take, , manipulate, data via address: pointer.
now. pointers pointers no different. pointers pointers hold addresses of (wait it...) pointers. our first example, this:
struct node { int data; struct node *next; } vod foo(node* ptr) { node *p = new node(); p->data = 0; p->next = ptr; ptr = p; } int main() { node *root = nullptr; foo(root); }
won't work. can fix several ways. 1 way using pointer-to-pointer (the c way). uses reference pointer (the c++ way).
first c way, demonstrates whole mantra of passing address means declaring parameter pointer-to type (in case pointer pointer type), , passing address of thing modify:
void foo(node** ptr) { node *p = new node(); p->data = 0; p->next = *ptr; ptr = p; } int main() { node *root = nullptr; foo(&root); // look: passing address of our root pointer }
do see how, in our trivial example using int
, int*
, have pass address of thing we're modifying function takes pointer-to-type? in case "type" is, itself, pointer type.
now, arguable, c++ way using reference trivial comparison, imho isn't clear going on, because there literally single character difference between version doesn't work , version does. @ this:
vod foo(node*& ptr) // added & { node *p = new node(); p->data = 0; p->next = ptr; ptr = p; } int main() { node *root = nullptr; foo(root); }
notice how everything else in identical version not work. has preferences, , knowing allows me use either method, can see why have such difficulty writing , debugging double-indirection code hidden in reference type. engineers prefer send all out-params pointer-to types, , i'm 1 of them.
peeling code
after of that, lets peel code , see things go hell. i'll dissect 1 not work, , can see why neither version good:
first type:
struct node { int value = 4; node* next; };
nothing horridly questionable here. default value assignment in structure definition. puke on non-current-day c++, throw out now. if want default value, make constructor (which should have anyway ensure members initialized something):
struct node { int value; node* next; node(int val = 4) : value(val) , next() {} };
ok. next up..
void insertfront(node*, node**);
you seem want use pure node interface. people writing linked list this:
void insertfront(node** pproot, int value);
but we'll go version now. actual implementation of this:
void insertfront(node* newhead, node** head2) { newhead->next = *head2; *head2 = newhead; }
is correct. yes orphan being pointed newhead->next
, doesn't seem concern of yours, go now.
finally torrent: main()
.
int main() { node head; head.value = 32; head.next = nullptr; node** headptr = new node*; (*headptr) = new node; *(*headptr) = head; (*headptr)->value = 32;//redundant, know (*headptr)->next = nullptr;//redundant, know cout << head.value << endl; insertfront(new node, headptr); cout << head.value << endl; system("pause"); return 0; }
this has multiple issues. first, mixing dynamic nodes non-dynamic nodes.
node head; head.value = 32; head.next = nullptr;
bad idea. no reasonable way calling code (in particular cleanup code deletes each node list), has clue whether being pointed dynamic or not. don't that.. using constructor version of node
above, should be:
node* head = new node(32);
next you're dynamically allocating pointer; (not node; pointer)
node** headptr = new node*;
bad idea. there no need @ all. have pointer variable list head (its called, not-coincidentally, head
). appears setup invoking insertion function. that, everything node** headptr = new node*;
on down can replaced this:
insertfront(new node(10), &head); // look: passing address of head pointer cout << head->value << endl;
Comments
Post a Comment