C - dynamic arrays

2019-07-05 04:52发布

问题:

I don't quite understand how pointers work with C arrays. Here's some code I got:

int arrayOne[] = {1, 2, 3};
int arrayTwo[] = {4, 5, 6, 7};

int **arrayThree = (int **)malloc(2 * sizeof(int));
arrayThree[0] = arrayOne;
arrayThree[1] = arrayTwo;

for (int i = 0; i < 2; i++) {
    int *array = arrayThree[i];
    int length = sizeof(array) / sizeof(int);
    for (int j = 0; j < length; j++)
        printf("arrayThree[%d][%d] = %d\n", i, j, array[j]);
}

I would have expected this to output the following:

arrayThree[0][0] = 1
arrayThree[0][1] = 2
arrayThree[0][2] = 3
arrayThree[1][0] = 4
arrayThree[1][1] = 5
arrayThree[1][2] = 6
arrayThree[1][3] = 7

What it actually prints out is:

arrayThree[0][0] = 1
arrayThree[0][1] = 2
arrayThree[1][0] = 4
arrayThree[1][1] = 5

Why?!

回答1:

sizeof(array) is the size of a pointer, which just happens to be the twice the size of an int on your platform.

There's no way to get the length of an array in C. You just have to remember it yourself.



回答2:

First of all, int **arrayThree = (int **)malloc(2 * sizeof(int)) is wrong, it should be sizeof(int *)

Next, sizeof(array) / sizeof(int) corresponds to sizeof(int *) / sizeof(int) which is not what you want.

There is no "embedded" size information in a pointer that you treat as an array, you will need to manually manage the size.



回答3:

There is no built-in mechanism to keep track of the size of an array in C, you need to maintain it yourself, and pass it to any function that takes your array as parameter.

However, if you really need to use arrays extensively and in a dynamic manner in C, you can build your own library of dynamic arrays in C, without too much effort. For more information, refer to the following tutorial: goo.gl/vYhkF.



回答4:

First of all, the allocation of arrayThree should be

int **arrayThree = malloc(2 * sizeof *arrayThree);

Since the type of arrayThree is int **, then the type of *arrayThree is int *.

The reason that sizeof (array) / sizeof (int) isn't returning what you expect is that array is a pointer (type int *), not an array type, so sizeof returns the number of bytes contained in the pointer object itself, not the number of elements pointed to.

There is no way to know from the pointer value alone how many elements are being pointed to; you must keep track of that information separately.