Reputation: 10580
What is the difference between initializing a variable x as char ** and initializing a variable x as char * and then using & to reference it? This question came up from the following inquiry:
I was looking at the man 3 strtol function. The function signature is:
long strtol(const char *restrict str, char **restrict endptr, int base);
So, to pass the endptr variable, I setup a variable:
char **endptr;
but when I passed it to the function it always returned NULL, even in cases where the str passed to strtol was something like abc.
I.E:
char ** endptr;
long exitval = strtol(args[1], endptr, 10); /* try to get the val */
if (endptr != NULL) { /* it wasn't a valid base-10 number */
Yet when I changed how I initialized endptr to:
char *endptr;
and then passed the endptr as &endptr to the function, endptr was set correctly. I.E:
char * endptr;
long exitval = strtol(args[1], &endptr, 10); /* try to get the val */
if (endptr != NULL) { /* it wasn't a valid base-10 number */
In both cases, I thought was I was passing was the a pointer to a pointer to the first char in a char array, but the fact that one method works and the other doesn't indicates my understanding is incorrect.
Why does one method work and the other doesn't? What am I misunderstanding?
Upvotes: 1
Views: 230
Reputation: 41812
I'll have a shot.
The function strtol
wants the address of something it can write to.
When you declare
char *ptr;
you have a variable called ptr
and when you pass its address, strtol
can write to that location and afterward you can use that value by looking at the contents of the variable.
When you declare
char **ptr;
and just pass its value, first of all you're probably passing an uninitialised value that strtol
will try to write to, and secondly, even if you initialise it you're passing just it's contents - strtol
will modify the location it points to, not the contents of the variable itself.
Upvotes: 3
Reputation: 319
From the man page :
If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr.
In the first case you pass the value of endptr
to strtol()
which was initialized to 0, so strtol()
will not store the address of the first invalid character in *endptr
.
In the second case you pass the address of endptr
to strtol()
, which is not 0, thus it will not return NULL if an invalid character is found.
Upvotes: 0
Reputation: 6037
In the first you are not giving a value to your pointer to a pointer, it is an uninitialised value you are passing to strtol, in the second you are defining a pointer and then you are getting the address of it, so you are passing the address of endptr.
Another way to think about it is, the first example you are defining a place in memory that is to holds a pointer to a pointer, but that memory is not set to anything, you are then passing that garbage to strol. The second one you are defining a place in memory that holds a pointer, you are then getting the address of the bit of memory and then passing it to strol.
Upvotes: 1