0

I am trying to make an 'int** arr[5]' the each cell in it contains an 'int* array', each 'int* array' has a different size. Whenever i am trying to print one of the cell it prints only the first number in it, why is it happening? how can i print the whole array?

#include <stdio.h>
#include <stdlib.h>

void sortNumber(int** arr[]);


int main(void)
{
    int i = 0;

    int* arr1[3] = { 2, 5, 8 };
    int* arr2[2] = { 1, 7 };
    int* arr3[6] = { 5, 1, 8, 3, 7 ,12 };
    int* arr4[4] = { 3, 9, 4, 29};
    int* arr5[5] = { 4, 11, 17, 23, 25 };

    int** bigArr[5] = {*arr1, *arr2, *arr3, *arr4, *arr5};

    sortNumber(bigArr);


    system("PAUSE");
    return 0;
}

void sortNumber(int** arr[])
{
    printf("%d", arr[1]);
}
xaxxon
  • 19,189
  • 5
  • 50
  • 80
Yazen Vid
  • 21
  • 3
  • 1
    Because you are only printing one element. Need a loop. – OldProgrammer Apr 09 '16 at 17:06
  • 5
    Your code has several problems. Please read up on "pointers". – Spikatrix Apr 09 '16 at 17:09
  • 1
    `*arr1` is of type `int *`, and the same is true of the other expressions used to initialize `bigArr`. If you used `&arr1[0]` instead (type "pointer to `int` pointer, or `int **`), then it would be fine. Aside from that, OldProgrammer is correct in that you need a loop. However, here's a question related to the loop idea: how do you know where the array passed to `sortNumber` ends? There is no `itemCount` parameter, and `bigArr` doesn't end with any sort of [sentinel value](https://en.wikipedia.org/wiki/Sentinel_value) such as a `NULL` pointer. –  Apr 09 '16 at 17:32
  • you have to choose between declaring int tables as tables or pointer (int arr[], or int *arr); recheck and analyze carefully your code. – milevyo Apr 09 '16 at 18:32
  • 1
    +1 to @ChronoKitsune's observations. To print out all array elements, you need to know how many are there. C does not have the luxury of an `array.length` property like you find in many other languages. As such, you need to define cleary define an `itemCount` (*or use a sentinel value, but that can get messy when you're dealing with integers*). You may want to consider using something like this: `struct iArray_s{ int *arr; int itemCount; }` This would create a struct that you can store your integer array in as well as a variable that can specify how many members the array contains. – Spencer D Apr 09 '16 at 18:33
  • I don't know what the heck was going on with #define FIVE 5, but it detracts STRONGLY from the understandability of the question, so I removed them. Also, for some reason it was marked as being javascript in comments causing the "run this snippet" to show up. Not sure how that happened, but you shouldn't do that. – xaxxon Apr 09 '16 at 19:33
  • @Ramsey CPUs don't understand C++ types, so your question is nonsensical. pointers are memory addresses. ints are some size of integer value. Pointer types don't exist on the CPU neither does what the definition of an int is in c++. – xaxxon Apr 09 '16 at 19:34

2 Answers2

0

So you are working with 2 dimensional array. You would need to print it in format arr[i][j].

for(int i = 0; i < THREE; i++)
   printf("%d", arr[THREE][i]);
Sia
  • 201
  • 1
  • 9
0

There are a couple of issues here. It's not completely clear to me what your goal is, but it looks like you want to deal with a 2 dimensional array where the 2nd dimension has different length entries.

int* arr1[3] = { 2, 5, 8 };

There you create an array containing pointers. You're initializing the elements with numbers, but those are pointers -- the entries point to the memory address denoted by the number. I.e. the first element points to memory address 2 -- is that really intended? If you want to store numbers you need to use a simple array here.

int** bigArr[5] = {*arr1, *arr2, *arr3, *arr4, *arr5};

Here you assigne the value of arr1 and so on to the elements of bigArr. However, since you dereference arr1 you don't get a pointer to the array. Instead you get the value of the first element (*arr1 is basically the same as arr1[0]). So now bigArr stores int** values, which are simply the first element of the subarray. No pointer to the subarrays is stored. You can access array elements via pointer or array access, and that's basically what's going wrong here.

Speaking about pointers in general: The following two lines behave identical:

int a = arr1[1];
int b = *(arr1 + 1);

as well as you can get a pointer to an array in two different ways. In the end both pointers point to the first element of the array:

int array[] = {1, 2, 3};
int *ptr1 = array;
int *ptr2 = &array[0];

Last, C doesn't store the length of an array -- you need to know this.

I'm assuming you want to store a data structure like this:

[
 [ 2, 5, 8 ],
 [ 1, 7 ],
 [ 5, 1, 8, 3, 7, 12 ],
 [ 3, 9, 4, 29 ],
 [ 4, 11, 17, 23, 25 ]
]

To do this you don't need double pointers. Also, you need to store the length of the subarray. An approach to this could be to use an array of struct.

struct row {
    int* data;
    int length;
};

int arr1[3] = { 2, 5, 8 };
int arr2[2] = { 1, 7 };
// ...

struct row r1 = {arr1, 3};
struct row r2 = {arr2, 2};
// ...
struct row *bigArr[] = {r1, r2, ...};

Now sortNumber changes to

void sortNumber(struct row* r)
{
    for(int i = 0; i < r->length; i++) {
        printf("%i ", r->data[i]);
    }
    printf("\n");
}
bluebrother
  • 8,636
  • 1
  • 20
  • 21