Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array of arrays, with different sizes

Tags:

arrays

c

pointers

I'm having an array, that has arrays in every cell. For example, the big array is called arr:

int a[3] = {3, 2, 1};
int b[2] = {2, 1};
int *arr[2] = {a, b}

Now the problem is, if I want to print the small arrs, inside the big array.

Here is my code:

#include <stdio.h>

void printArr(int arr [], int n)
{
    for (int i = 0 ; i < n ; i++)
    {
        printf("%d ", *(arr + i));
    }
    printf("\n");
}

int main()
{
    int a[5] = {1, 8, 4, 2, 0};
    int b[3] = {1, 4, 2};
    int *arr [2] = {a, b};

    int n = 0;

    for (int i = 0 ; i < 2 ; i++)
    {
        printArr(*(arr + i), n);
    }
}

The output is supposed to be something like this:

1 8 4 2 0 1 4 2

But I can't get the size of each array, since sizeof(*(arr + i) gives me 4, which is the size of the pointer (the name of the array), and not all the array it self. So what can I do?

Thanks!

like image 482
Amit Avatar asked Mar 30 '14 15:03

Amit


2 Answers

The Problem:

The C language only provides a way of finding the size of types. This gives the subtle differences between applying sizeof to:

1) An array of a type such as:

int a[3];
sizeof(a); // => 3 * sizeof(int)

2) A pointer to the type:

int *ptr;
sizeof(ptr); // => sizeof(int *)

or

int a[3] = {3, 2, 1};
int b[2] = {2, 1};
int *arr[2] = {a, b};

sizeof(arr[1]); // => sizeof(int *)

Some solutions:

Store the size

As jfly proposes store the size of the arrays.

  • Makes finding the size a constant time operation.

Append an end marker

Adding a end marker like '\0' as used for c-style strings. You might use INT_MAX or INT_MIN in this case.

The printArr implementation would need to change to:

void printArr(int *arr)
{
    int *it = arr;
    while(arr != INT_MIN);
    {
        printf("%d ", *it);
    }
    printf("\n");
}

Disadvantages:

  • Finding the size of the array requires iterating over the full array.
  • Gives the risk of an actual value colliding with the end marker value.

Advantages:

  • The varying sized array can be passed as a single argument.

Using iterators

Store the pointer to the first and one past the last value.

void printArr(int *begin, int *end)
{
    for (int *it = begin; it != end; it++)
    {
        printf("%d ", *it);
    }
    printf("\n");
}

int *end_arr[2] = {a + 3, b + 2};

for (int i = 0 ; i < 2 ; i++)
{
    printArr(arr[i], end_arr[i]);
}
  • Can be extended to other data structures.
like image 175
PeterSW Avatar answered Oct 17 '22 06:10

PeterSW


Since arr is an array of pointers, so you can't get the size of array from the pointer which points to an array, you need additional size info:

    int size_arr[2] = {sizeof(a) / sizeof(int), sizeof(b) / sizeof(int)};

    for (int i = 0 ; i < 2 ; i++)
    {
        printArr(arr[i], size_arr[i]);
    } 
like image 23
jfly Avatar answered Oct 17 '22 06:10

jfly