(e-mail address removed) writes:
char **a;
int numberOfPointers = 5;
a = (char **) malloc ( numberOfPointers * ( sizeof(char * ) ) );
if ( a!= NULL )
printf( "the array, a, points to declare space\n\n" );
char *b[] = { "one", "two", "three", "four", "five" };
a = b;
It's possible that you don't know what this assignment does. It only
replaces one pointer with another. The pointer value that used to be in
'a' is lost so you can no longer access the memory that was allocated.
in particular, you can't ever free it now.
<snip>
Ben, so a=b; , does not assign a to point to whatever b points to?
C has special many special rules for arrays, like b. One of those rules
says that, in most context, an lvalue of array type is automatically
converted into a pointer to the first element of that array. This is one
of those contexts. There are three exceptions to that rule:
char *(*c)[5] = &b;
'b' does not get converted into a pointer to it's first element; instead
it remains an array, so &b has the type char*(*)[5].
The second exception is
size_t array_size = sizeof b;
which gives the size of b, and not the size of a pointer to the first
element of b.
The third exception is:
char array[] = "string literal";
where the string literal is an lvalue of array type, but instead of
being automatically converted into a pointer to char (which would be a
constraint violation in this context), it gets used to initialize the
array, exactly as if I had written:
char array[] = {'s', 't', 'r', 'i', 'n', 'g', ' ',
'l', 'i', 't', 'e', 'r', 'a', 'l', '\0'};
In all other contexts, an lvalue of array type gets automatically
converted into a pointer to the first element of the array. This rule
often leads people into confusing pointers and arrays, but they are
quite different (though closely related) things.
As a result of that conversion, the line "a=b;" causes a to contain a
pointer to the first element of b.
Yes, just like numberOfPointers = 6 would cause the value of 5, which is
currently stored in numberOfPointers, to be replaced with the value of
6. That isn't much of a problem, unless you have some need to know what
the old value was - then it becomes a BIG problem.
In this case, before the line "a=b;", the variable 'a' contained a
pointer to memory that had been allocated by a call to malloc(). After
the assignment, 'a' contained a pointer to the first element of b. There
is no other copy of the pointer that used to be stored in 'a'. That
means you no longer have any way to access the memory that the pointer
pointed at. This also means you have no way of freeing that memory.
I thought it was having a point to the same memory location.
How would you do that? How would you have a point to b? what is the syntax?
If you want a to point at the first element of 'b', then there's
absolutely nothing wrong with using "a=b;". The problem is not about
having 'a' point at 'b'. However, 'a' can only point at one thing, it
can either point at the memory you allocated with a call to malloc(), or
it can point at 'b'; it can't point at both. If you want to point at two
different things, then you need two different pointers.
Of course, in this context, it would be a good question to ask why you
want to point at two different things. It would be an even better
question to ask why you have two different things to point at - your
code makes no use of the memory allocated by that call to malloc(), so
your program has no obvious reason for bothering to allocate that memory
in the first place.
What did you think you were allocating that memory for? Whatever it was,
your code isn't actually doing it.