dumboo said:
hi there
i m little bit confused over the following problem, i have understood
wt the following code is doing...but not able to get the actual
techinical stuff.....i have had a lot of hot debate over the
following code whether its pass by reference or pass by value...hope
somebody clears it up
void foo(char *s)
{
s = new char[10];
strcpy(s, "gotit");
}
int main()
{
char *s;
foo(s);
cout<<s;
delete s;
return 0;
}
regards
There is some confusion here resulting from C++'s origin in C. The C
language does not have C++-style references. Accordingly, if you want a
function in C to modify something, you need to pass it a pointer to the
thing to be modified. In C, this is called "passing by reference". Now
consider your function:
void foo(char *s)
{
s = new char[10];
strcpy(s, "gotit");
}
In C, this would be called "passing by reference". The important thing to
note, however, is that the thing that is passed by reference is *not* the
variable s but what s points to, i.e., s is passed by value and what s
points to is passed by reference. What this means is that
1. foo receives a local copy of s and any changes that it makes to s only
affect that local copy.
2. the copy of s that foo receives points to the same memory area as the
original s did, so any changes made to what s points to have the same effect
within the function as they would have in the place from which the function
is called.
In your line:
s = new char[10];
you are changing the local copy of s, which has no effect on the original s.
Thus cout in main() is being applied to the uninitialised s.
If you want to modify s, then there are two ways to go about it. The C-style
approach is to pass the address of s rather than s itself, as follows:
void foo(char **ps)
{
*ps = new char[10];
strcpy(*ps, "gotit");
}
int main()
{
char *s;
foo(&s);
cout << s;
delete[] s;
return 0;
}
Note:
1. Since s is a pointer, a variable storing the address of s is a pointer to
pointer. Thus there is a double asterisk in the definition of foo's
parameter. ps is a pointer to s, so *ps gives the original s. Hence *ps
replaces s in your foo function.
2. foo is called with an argument of &s rather than with an argument of s.
3. I have changed your original delete to the (correct) array form of
delete[].
The C++-style approach is to use references as follows:
void foo(char *& s)
{
s = new char[10];
strcpy(s, "gotit");
}
int main()
{
char *s;
foo(s);
cout << s;
delete[] s;
return 0;
}
This involves the least change to your code. All you need to do is replace
void foo(char *s)
with
void foo(char *& s)
i.e., you only need add the & symbol. This change means that s itself ---
and not just what it points to --- is "passed by reference" (in the C++
sense of that term). This means that foo operates on the original s --- no
local copy is made --- so that any changes that foo makes to s affect the
original.