Please take a look at the following code. It tries to pass an array as a char**
to a function:
#include <stdio.h> #include <stdlib.h> static void printchar(char **x) { printf("Test: %c\n", (*x)[0]); } int main(int argc, char *argv[]) { char test[256]; char *test2 = malloc(256); test[0] = 'B'; test2[0] = 'A'; printchar(&test2); // works printchar((char **) &test); // crashes because *x in printchar() has an invalid pointer free(test2); return 0; }
The fact that I can only get it to compile by explicitly casting &test2
to char**
already hints that this code is wrong.
Still, I'm wondering what exactly is wrong about it. I can pass a pointer to a pointer to a dynamically allocated array but I can't pass a pointer to a pointer for an array on the stack. Of course, I can easily work-around the problem by first assigning the array to a temporary variable, like so:
char test[256]; char *tmp = test; test[0] = 'B'; printchar(&tmp);
Still, can someone explain to me why it doesn't work to cast char[256]
to char**
directly?
To declare a pointer to an array type, you must use parentheses, as the following example illustrates: int (* arrPtr)[10] = NULL; // A pointer to an array of // ten elements with type int. Without the parentheses, the declaration int * arrPtr[10]; would define arrPtr as an array of 10 pointers to int.
C. In this program, we have a pointer ptr that points to the 0th element of the array. Similarly, we can also declare a pointer that can point to whole array instead of only one element of the array. This pointer is useful when talking about multidimensional arrays.
Because it will cause undefined behavior in your program. Show activity on this post. If you return a pointer to a local variable once the function returns it is out of scope. From then on it is undefined behavior if you access the returned pointer.
A stack pointer is a small register that stores the memory address of the last data element added to the stack or, in some cases, the first available address in the stack.
test
is an array, not a pointer, and &test
is a pointer to the array. It is not a pointer to a pointer.
You may have been told that an array is a pointer, but this is incorrect. The name of an array is a name of the entire object—all the elements. It is not a pointer to the first element. In most expressions, an array is automatically converted to a pointer to its first element. That is a convenience that is often useful. But there are three exceptions to this rule:
sizeof
.&
.In &test
, the array is the operand of &
, so the automatic conversion does not occur. The result of &test
is a pointer to an array of 256 char
, which has type char (*)[256]
, not char **
.
To get a pointer to a pointer to char
from test
, you would first need to make a pointer to char
. For example:
char *p = test; // Automatic conversion of test to &test[0] occurs. printchar(&p); // Passes a pointer to a pointer to char.
Another way to think about this is to realize that test
names the entire object—the whole array of 256 char
. It does not name a pointer, so, in &test
, there is no pointer whose address can be taken, so this cannot produce a char **
. In order to create a char **
, you must first have a char *
.
Because test
is not a pointer.
&test
gets you a pointer to the array, of type char (*)[256]
, which is not compatible with char**
(because an array is not a pointer). This results in undefined behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With