1

I am trying to declare a 3D array and store value into the 3D array using pointer. But I can get the inputs using scanf but the output always prints the address instead of the value of the array. Below is my code. What am I doing wrong here?

#include <stdio.h>

void main()
{
   int b[3][3][3];
   int l1,l2,l3;
   int *pa2[3][3];

   pa2[3][3]=b;

   for(l1=0;l1<3;l1++)
   {
      for(l2=0;l2<3;l2++)
      {
         for(l3=0;l3<3;l3++)
         {
            scanf("%d",(((pa2+l1)+l2)+l3));
         }
      }
   }

   for(l1=0;l1<3;l1++)
   {
      for(l2=0;l2<3;l2++)
      {
         for(l3=0;l3<3;l3++)
         {
            printf("%d\n",*(((pa2+l1)+l2)+l3));
         }
      }
   }
}
R Sahu
  • 200,579
  • 13
  • 144
  • 260
Kiran C K
  • 61
  • 7
  • @SouravGhosh Actually there is . See scanf part below . – ameyCU Aug 07 '15 at 16:27
  • You are using `void main` and have tagged a C question with the C++ tag. Those two things are most wrong about the question! :) – Christian Hackl Aug 07 '15 at 16:31
  • Simply adding l1, l2, and l3 is wrong. We need to multiply and add to get the correct addresses. – Matthias J. Sax Aug 07 '15 at 16:35
  • 1
    Please note that a 3D-array in C is an array of an array of an array. – alk Aug 07 '15 at 16:39
  • @MatthiasJ.Sax No multiplication is needed. – this Aug 07 '15 at 16:41
  • `int *pa2[3][3]; pa2[3][3]=b;` does not look right, no matter what the language... – crashmstr Aug 07 '15 at 16:47
  • your code has bugs. During the loop execution `l1=0,l2=0,l3=1` and `l1=0,l2=1,l3=0`will modify the same memory location. – Pawan Aug 07 '15 at 16:52
  • `(((pa2+l1)+l2)+l3))` is equivalent to `(pa2 + l1 + l2 + l3)`, so `*(((pa2+l1)+l2)+l3)` is equivalent to `pa2[l1 + l2 + l3]`. (`&pa2[0]`, which `pa2` decays into, is an `int*(*)[3]`, and pointer arithmetic doesn't ever result in a different pointer type.) – molbdnilo Aug 07 '15 at 17:15
  • I just updated my answer with usage of multiplication... Just for the sake of argument ;) – Matthias J. Sax Aug 08 '15 at 17:12

4 Answers4

1

Why do you use pointer pa2 at all? Use

scanf("%d",&b[l1][l2][l3]);

and

printf("%d\n",b[l1][l2][l3]);

If you insist on using points, you need to get the pointer arithmetics right. Array memory is laid out continuously (compare How are multi-dimensional arrays formatted in memory?). The following example would do the trick:

#include <stdio.h>

int main(int argc, char **argv) {
    int a[3][4][5];
    void *p = a;

    int x = 0;
    int i, j, k;
    for(i = 0; i < 3; ++i) {
        for(j = 0; j < 4; ++j) {
            for(k = 0; k < 5; ++k) {
                a[i][j][k] = x++;
            }
        }
    }

    const size_t s = sizeof(int);
    for(i = 0; i < 3; ++i) {
        for(j = 0; j < 4; ++j) {
            for(k = 0; k < 5; ++k) {
                printf("%d ", *(int*)(p + 20*i*s + 5*j*s + k*s));
            }
            printf("\n");
        }
        printf("\n");
    }

    return 0;
}
Matthias J. Sax
  • 55,617
  • 7
  • 102
  • 126
1

Your use of pointer pa to access the array is wrong in both the scanf line and the printf line.

You have

scanf("%d",(((pa2+l1)+l2)+l3));

What does (((pa2+l1)+l2)+l3) evaluate to?

It is simply (pa2+l1+l2+l3). I am sure that's not what you meant to do. By using this, you have a program that is subject to undefined behavior.

You can use:

&(pa2[l1][l2][l3])

If you insist on using the less clear form, you'll need to use:

(*(*(pa2+l1) + l2) + l3)

For the printf statement, you can use:

printf("%d\n", pa2[l1][l2][l3]);

or

printf("%d\n", *(*(*(pa2+l1)+l2)+l3));

Update

The declaration of pa2 and the line to set its are also wrong.

Instead of

int *pa2[3][3];
pa2[3][3]=b;

You need:

   int (*pa2)[3][3];    
   pa2=b;

or a one liner:

   int (*pa2)[3][3] = b;
R Sahu
  • 200,579
  • 13
  • 144
  • 260
  • `&(pa2[l1][l2][l3])` due to this program crashes while taking input. Please check it once more. – ameyCU Aug 07 '15 at 17:25
0

A 3D-array is an array of an array of an array, hence after adding the offset to the pointer you need to dereference it and start over:

*(*(*(pa + l1) + l2) + l3)

this is equivalent to:

pa[l1][l2][l3]
alk
  • 68,300
  • 10
  • 92
  • 234
-2

I'm not sure what you are really trying to accomplish with this program, but I think I see part of the problem.

printf("%d\n",*(((pa2+l1)+l2)+l3));

You should de-reference the pointer before attempting to add values to it.

Hence:

(((*pa2 + l1)+l2)+l3)

Otherwise, you are performing pointer arithmetic and that is likely why you see a hexadecimal address in your output.

h0r53
  • 2,561
  • 2
  • 13
  • 23
  • That is not the correct way of getting the element. Not only is the wrong type, worse, it points way out of bounds. – this Aug 07 '15 at 16:38