Discussion:
Difference between calls to void Func1(char *p); and void Func2(char **p)
Add Reply
b***@gmail.com
2017-05-11 16:06:49 UTC
Reply
Permalink
Raw Message
In the program below, why does the call to Func1 not change the value pointed to by ptr; whereas the call to Func2 manages to change the value?
Thanks in advance.

void Func1(char *p)
{ p = "McCartney"; }

void Func2(char **p)
{ *p = "Harrison"; }

int main()
{ char *ptr = "Lennon";
ptr = "Starr"; std::cout << ptr << endl;

Func1(ptr); std::cout << ptr << endl; // Doesn't change
Func2(&ptr); std::cout << ptr << endl;
}
gwowen
2017-05-11 16:14:40 UTC
Reply
Permalink
Raw Message
Post by b***@gmail.com
In the program below, why does the call to Func1 not change the value pointed to by ptr; whereas the call to Func2 manages to change the value?
Thanks in advance.
void Func1(char *p)
{ p = "McCartney"; }
Because here "p" is local variable that contains the address of (i.e. points to) "Starr".

Then you change that so that local variable contains the address of (points to) the string "McCartney". But you've only changed the local variable ("p =" means change p), not the object at the address pointed to so the original ptr variable is unchanged.

In the second case, the local variable p contains the address of (points to) the variable ptr. So when you dereference it and modify you change the pointed-to thing, which is ptr.

" p = " means "make p point at a different thing"
"*p = " means "modify the thing pointed at by p"
Stefan Ram
2017-05-11 16:20:32 UTC
Reply
Permalink
Raw Message
Post by b***@gmail.com
void Func1(char *p)
{ p = "McCartney"; }
void Func2(char **p)
{ *p = "Harrison"; }
int main()
{ char *ptr = "Lennon";
ptr = "Starr"; std::cout << ptr << endl;
Func1(ptr); std::cout << ptr << endl; // Doesn't change
Func2(&ptr); std::cout << ptr << endl;
}
»Func1« only changes its own local variable (parameter) »p«.
This is a change that is not visible outside of that function.
It has no effect on »ptr«. On invocation, only a copy of the
value of »ptr« was passed to »p«. So »Func1« has no means to
access »ptr«.

»Func2« changes what »p« points to, that is, »ptr«.
Barry Schwarz
2017-05-11 16:24:33 UTC
Reply
Permalink
Raw Message
Post by b***@gmail.com
In the program below, why does the call to Func1 not change the value pointed to by ptr; whereas the call to Func2 manages to change the value?
Because C passes arguments to functions by value. The only way to
change the value pointed to by a pointer is to dereference the
pointer.
Post by b***@gmail.com
Thanks in advance.
void Func1(char *p)
{ p = "McCartney"; }
Func1 does not dereference p. The assignment statement updates p (a
variable local to Func1) which is a copy of ptr in main. That copy is
destroyed when Func1 returns. At no time did any code in Func1
attempt to access ptr.
Post by b***@gmail.com
void Func2(char **p)
{ *p = "Harrison"; }
p points to ptr in main. Since the assignment dereferences p, it
accesses the object pointed to which is ptr in main. ptr is then
assigned a new value. The value in p is not changed; it still points
to ptr. p is also destroyed when Func2 exits.
Post by b***@gmail.com
int main()
{ char *ptr = "Lennon";
What purpose do you think the initialization serves?
Post by b***@gmail.com
ptr = "Starr"; std::cout << ptr << endl;
If you want to ask questions about C++, you should do so in
comp.lang.c++.
Post by b***@gmail.com
Func1(ptr); std::cout << ptr << endl; // Doesn't change
Func2(&ptr); std::cout << ptr << endl;
}
--
Remove del for email
Ben Bacarisse
2017-05-11 16:28:00 UTC
Reply
Permalink
Raw Message
Post by b***@gmail.com
In the program below, why does the call to Func1 not change the value
pointed to by ptr; whereas the call to Func2 manages to change the
value?
First off, this is a C++ program. Even with a program this simple there
are differences between C and C++. C++ has a better way to do what you
are doing, and if you ask in comp.lang.c++ you will probably get better
help.
Post by b***@gmail.com
void Func1(char *p)
{ p = "McCartney"; }
No changes to a parameter are ever seen outside of a C function because
arguments are passed strictly by value. p gets a value from the call,
but p (and any altered value it may have been given) gets thrown away
when the function returns. This is A Good Thing[1] -- it keeps the
effects of a function as local as possible.
Post by b***@gmail.com
void Func2(char **p)
{ *p = "Harrison"; }
Here, the value in p is being used to access something outside of the
function, specifically that object pointed to by p. By passing &ptr in
main, you ensured that fr this call at least, p points to the ptr
variable in main. This is not A Good Thing, but it is sometimes
necessary.
Post by b***@gmail.com
int main()
{ char *ptr = "Lennon";
ptr = "Starr"; std::cout << ptr << endl;
Func1(ptr); std::cout << ptr << endl; // Doesn't change
Func2(&ptr); std::cout << ptr << endl;
}
[1] See "1066 and All That: A Memorable History of England, comprising
all the parts you can remember, including 103 Good Things, 5 Bad
Kings and 2 Genuine Dates".
--
Ben.
b***@gmail.com
2017-05-14 14:36:21 UTC
Reply
Permalink
Raw Message
Thanks to gwowen, Barry and Ben, particularly Barry and Ben. Your explanations helped a lot.
Loading...