arnuld said:
pointer to the whole array ? char* is a pointer to char, int** is a
pointer to pointer to int. How you get pointer to array, I mean what type
it is?
I was being a bit vague. Lets leave actual array pointers out of
this. I mean that Richard was talking about changing the char ** as
seen from the calling function. The thing you are intending to pass,
a char **, is in some sense a pointer to the whole array: from it all
of the array's data is accessible. The trouble is you can can't
change this char ** inside the function -- not in a way that has any
effect outside. All you can do is change the various things it points
to.
If a function needs to change an int, you pass an int *. If it needs
to change int *, you pass an int **. If it needs to change and int **
you must pass an int ***.
A function
that takes: void get_word(char **words); can change words[32] to point
to some new string just found.
Right. And words++ will take us to the 2nd element of the array.
Right. With no visible effect outside. Just as:
void f(int x)
{
x++; /* changes x but has no effect on anything passed */
}
It can change words[32][0] to be 'x',
but it can't change words itself. Well, it can, but the effect will
be lost when the function returns.
Now here is the problem where my understanding about pointers and arrays
blows away:
get_word( char* words[3] )
(First, the declaration is confusing because the 3 has no effect.
Pretend you wrote get_word(char **words)
.
so we can change where words[0], [1] and [2] point because array will be
converted to pointer to first element and pointer *always* changes the
original element.
Absolutely. Now, having set words[0], words[1] and words[2] what
happens when you need to set sets words[3]. You can't. You need to
realloc some more space (always assuming that this is how the function
is supposed to work). That means changing words:
char **new_space = realloc(words, new_size * sizeof *new_space);
if (new_space) {
/* set up new space with all the right pointer in it... */
words = new_space;
}
Now what? words has more space and you can set words[3], but the
calling function will never see it. The calling function will still
have the old vale of that is passed (we can't even say what it is
called since it is just a pointer value) and, worse, that pointer now
points to storage invalidated by the realloc call.
Yes, but some_function can't make pc point to a bigger array if needed.
pc will point to the same place after the call.
yes, it means I can understand arrays and pointers
arrp[0] = p1;
arrp[1] = p2;
All these last three lines make no changes. Both elements of arrp are
already NULL.
There is difference. First array had NULL elements. Now arrays has
pointers which point to NULL. There is a difference.
No. I don't know how to explain this because I can't see the source
of your confusion. Writing:
char* arrp[ARRSIZE] = { 0 };
p1 = p2 = NULL;
arrp[0] = p1;
arrp[1] = p2;
as you did, is just like writing:
int arr[ARRSIZE] = { 42, 42 };
i1 = i2 = 42;
arr[0] = i1;
arr[1] = i2;
All the elements were 42 to start with and the are 42 after the
assignments. All I did was change the type. Everything is an int
rather than a char *.
That I know, x is a variable in the example and variables are passed as
value. Pointers and arrays are passed as references, hence we can change
the original elements.
Excellent! It words the same with a pointer -- provided you think
about the value of the pointer itself
then why that values does not appear ?
Typo! I meant you *can't* write any value into **ppc! Sorry. There
are two typos, I now see. It should have read: "*ppc is NULL -- you
set it to be NULL before the call. You can't write any value into
**ppc."