简体   繁体   中英

Pointer and memory confusion in C

If I have the following line of code:

int* a[3];

Does that mean it is a pointer to the first item in an array of 3 integers (thus, giving it a size of 4 bytes)? Or does it mean it is an array of 3 pointers (giving it a size of 12 bytes)?

It is the array of pointers to int data type in C programming language. Therefore, each element of this array can hold an address of a variable of int data type.

 int x=5, y=9, z=8;
 int *a[3]; // Declare an array of pointers to int

 a[0] = &x;
 a[1] = &y;
 a[2] = &z;

However, the declaration like below will declare a pointer to an array of 3 int .

int (*a)[3];

Size of a is dependent on the platform for which you will compile your code. Please use sizeof operator for determining size in your platform.

 int *a[3];
 printf("Size of a: %zu\r\n", sizeof(a));  

NOTE:

To print result of sizeof operator, use %zu if your compiler supports C99; otherwise, or if you want maximum portability, the best way to print a size_t value is to convert it to unsigned long and use %lu. You can read about it over here .

In order to understand expressions and declarations you must know the operator precedences. There are plenty online, for example here.

On that page you can see that angle brackets have a higher priority than the dereferencing asterisk, which means that they are applied first. If you like you can bracket parts of the declaration with parentheses, just like in an expression:

int *(a[10]); // brackets are redundant and show operator precedence

Therefore, the variable a must be an array. The array element resulting from the indexing yields, after the dereferencing operator is applied, an int , so that the element must be a pointer to int.

Thus, the declaration declares an array of int pointers.

As an extra, you cannot declare a pointer to an array without parentheses or typedefs, just because the operator precedences are made for the much more common case above. A pointer to an array would look like this:

int (*a)[10]; // brackets are necessary to make "*" apply first

Here, the dereferencing asterisk is applied first; a therefore must be a pointer. The resulting type can be indexed, therefore must be an array, whose elements are declared int s. This makes a a pointer to an array of int s.

You can test this yourself with the following code:

#include <stdio.h>
int main()
{
        int *a[3];
        printf("%zu\n", sizeof(a));
        return 0;
}

The output is 12, which, on the machine I'm testing it on, and apparently yours too from what you wrote in your question, is 3*sizeof(int) .

Type declaration precedence in C puts the "array" declaration [] one step above the "pointer to" declaration ( * ), so the declaration is:

Declare 'a' as an array of 3 pointers to type 'int'

You can use parentheses ( () ) to change the order in which the type declaration is processed:

int (*a)[3];

sizeof(a) gives it an output of 4, which on your machine is the size of a pointer.

As a side note, it's generally bad practice to assume that a pointer is always 4 bytes and that an int is always 4 bytes. This varies depending on architecture, compiler, CPU mode, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM