In code I would typically use:
#include <stdlib.h>
void dref1(char **blah)
{
(*blah)[0] = 'a';
(*blah)[1] = 'z';
(*blah)[2] = 0x00;
}
/* or */
void dref2(char **blah)
{
char *p = *blah;
*p++ = 'w';
*p++ = 't';
*p = 0x00;
}
int main(void)
{
char *buf = malloc(3);
dref1(&buf);
puts(buf);
dref2(&buf);
puts(buf);
free(buf);
return 0;
}
My question is if it is possible / how to dereference and increment pointer directly:
**blah = 'q'; /* OK as (*blah)[0] ? */
(*blah)++; /* Why not this? */
*((*blah)++) = 'w'; /* ;or. */
...
Whether the pointed-to value is a pointer or simply an integer doesn't matter. This has to do with the precedence of the unary * operator and the postfix ++ operator. In the absence of parentheses, the ++ operator is applied first and its result is used as the operand of the * operator.
When a pointer is incremented, it actually increments by the number equal to the size of the data type for which it is a pointer. For Example: If an integer pointer that stores address 1000 is incremented, then it will increment by 2(size of an int) and the new address it will points to 1002.
To get the value pointed to by a pointer, you need to use the dereferencing operator * (e.g., if pNumber is a int pointer, *pNumber returns the value pointed to by pNumber . It is called dereferencing or indirection).
I don't know what your real intent is, but it seems to me that you need to learn the difference between *p++
and (*p)++
as expressions.
The first expression dereferences the pointer and advances the pointer itself, not the value that is being pointed to.
The second expression dereferences the pointer and modifies the pointed-to value by applying the postfix ++
operator. Whether the pointed-to value is a pointer or simply an integer doesn't matter.
This has to do with the precedence of the unary *
operator and the postfix ++
operator. In the absence of parentheses, the ++
operator is applied first and its result is used as the operand of the *
operator.
EDIT:
Assuming that blah
is of type char **
, here is a list of the possible operations and what each one would do:
blah
yields a value of type char **
;*blah
yields char *
;**blah
yields char
;*(*blah)++
dereferences blah
to get a char *
, and then the *p++
analogy comes.**blah++
dereferences blah
twice to get the pointed-to value and then increments the blah
pointer.(**blah)++
dereferences the blah
pointer twice, and then the (*p)++
analogy comes.Yes, we can. Just test a litter. I think you have the idea.
The problem with using blah
the way you write, is, that when you come back to main, not only the content of the buffer is changed (correctly as you whant), but the pointer buf
itself too. That may be not what you want, and definetivily not what you need to free.
Test:
#include <stdlib.h>
void dref1(char **blah)
{
(*blah)[0] = 'a';
(*blah)[1] = 'z';
(*blah)[2] = 0x00;
}
/* or */
void dref2(char **blah)
{
char *p = *blah;
*p++ = 'w';
*p++ = 't';
*p = 0x00;
}
void dref3(char **blah)
{
*(*blah)++ = 'w';
*(*blah)++ = 't';
*(*blah) = 0x00;
}
void dref4(char **blah)
{
**blah = 'q'; /* OK as (*blah)[0] ? */
(*blah)++; /* Why not this? */
*((*blah)++) = 'w'; /* ;or. */
}
int main(void)
{
char *buf = (char*)malloc(3);
char *buf1=buf;
dref1(&buf);
puts(buf);
dref2(&buf);
puts(buf);
dref3(&buf);
puts(buf);
puts(buf1);
buf=buf1;
dref4(&buf);
puts(buf);
puts(buf1);
free(buf1);
return 0;
}
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