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
  • 204,454
  • 14
  • 159
  • 270
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

3 Answers3

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
  • 59,682
  • 7
  • 117
  • 137
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
  • 204,454
  • 14
  • 159
  • 270
  • `&(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
  • 69,737
  • 10
  • 105
  • 255