What does *p mean when **p is already declared

删除回忆录丶 提交于 2020-02-23 04:30:09

问题


Code

short **p = (short **)malloc(sizeof(short *));
*p = malloc(sizeof(short));
**p = 10;
printf("**p = %d", **p);

Output

**p = 10

In this code, a multiple pointer **p is declared and *p is used without any declaration(maybe it's by **p).

What does *p mean in my case? Sorry for very simple question.

I saw C standard and stack overflow, but I couldn't find out something.


回答1:


For any array or pointer p and index i, the expression p[i] is exactly equal to *(p + i) (where * is the unary dereference operator, the result of it on a pointer is the value that the pointer is pointing to).

So if we have p[0] that's then exactly equal to *(p + 0), which is equal to *(p) which is equal to *p. Going backwards from that, *p is equal to p[0].

So

*p = malloc(sizeof(short));

is equal to

p[0] = malloc(sizeof(short));

And

**p = 10;

is equal to

p[0][0] = 10;

(**p is equal to *(*(p + 0) + 0) which is equal to *(p[0] + 0) which is then equal to p[0][0])


It's important to note that the asterisk * can mean different things in different contexts.

It can be used when declaring a variable, and then it means "declare as pointer":

int *p;  // Declare p as a pointer to an int value

It can be used to dereference a pointer, to get the value the pointer is pointing to:

*p = 0;  // Equal to p[0] = 0

And it can be used as the multiplication operator:

r = a * b;  // Multiply the values in a and b, store the resulting value in r



回答2:


short **p = (short **)malloc(sizeof(short *));

This line declares a pointer to a pointer p. Additionally the value of p is set to the return value from malloc. It is equivalent to

short **p;
p = (short **)malloc(sizeof(short *));

The second line

*p = malloc(sizeof(short));

Here *p is the value of p. *p is of type pointer. *p is set to the return value of malloc. It is equivalent to

p[0] = malloc(sizeof(short));

The third line

**p = 10;

**p is the value of the value of p. It is of type short. It is equivalent to

p[0][0] = 10

In effect what the code above does is to allocate a 2D array of short, then allocate memory for the first row, and then set the element p[0][0] to 10.

As a general comment on your code, you should not use typecast in malloc. See Do I cast the result of malloc?




回答3:


What does *p mean when **p is already declared?

short **p = (short **)malloc(sizeof(short *));

(better written as)

short **p = malloc (sizeof *p);

Declares the pointer-to-pointer-to short p and allocates storage for a signle pointer with malloc and assigns the beginning address for that block of memory to p. See: In C, there is no need to cast the return of malloc, it is unnecessary. See: Do I cast the result of malloc?

*p = malloc(sizeof(short));

(equivalent to)

p[0] = malloc (sizeof *p[0]);

Allocates storage for a single short and assigns the starting address for that block of memory to p[0].

**p = 10;

(equivalent to)

*p[0] = 10;

(or)

p[0][0] = 10;

Assigns the value 10 to the dereference pointer *p[0] (or **p or p[0][0]) updating the value at that memory address to 10.

printf("**p = %d", **p);

Prints the value stored in the block of memory pointed to by p[0] (the value accessed by dereferencing the pointer as *p[0] or **p)

The way to keep this straight in your head, is p is a single pointer of type pointer-to-pointer-to short. There are 2-level of indirection (e.g. pointer-to-pointer). To remove one level of indirection, you use the unary * operator, e.g.

*p          /* has type pointer-to short */

or the [..] also acts as a dereference such that:

p[0]        /* also has type pointer-to short */

You still have a pointer-to so you must remove one more level of indirection to refernce the value stored at the memory location pointed to by the pointer. (e.g. the pointer holds the address where the short is stored as its value). So you need:

**p         /* has type short */

and

*p[0]       /* also has type short */

as would

p[0][0]     /* also has type short */

The other piece to keep straight is the type controls pointer-arithmetic. So p++ adds 8-bytes to the pointer-to-ponter address so it now points to the next pointer. If you do short *q = (*p)++; (or short *q = p[0]++, adds 2-bytes to the address for the pointer-to-short, soqnow points to the nextshortin the block of memory beginning at*p(orp[0]`). (there is no 2nd short because you only allocated 1 -- but you get the point)

Let me know if you have further questions.




回答4:


Let me put it in different way,

consider an example,

int x;
int *y = &x;
int **z = &y;
x = 10;

Which simplifies to this,

Note: Only for illustration purpose I have chosen address of x,y,z as 0x1000,0x2000,0x3000 respectively.

What does *p mean in my case?

In short the snippetshort **p = (short **)malloc(sizeof(short *)); is dynamically allocating a pointer to a pointer of type short i.e same asy in my example.



来源:https://stackoverflow.com/questions/59962025/what-does-p-mean-when-p-is-already-declared

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!