0

I am trying to get a pointer to an array integers to be temporarily remapped in a function later on to save myself pointer math. I've tried to see if any other questions answered it, but I've been unable to reproduce the methods described here, here, and here.

Fundamentally, I just want to temporally treat an integer group and a 3D array to be sure that I don't mess up the pointer math. (I'm looking at this currently because the previous code had made inconsistent assignments to the memory).

#include <stdlib.h>
#define GROUPCOUNT 16
#define SENSORCOUNT 6
#define SENSORDIM   3
int main()
{
int *groupdata = (int *)calloc(GROUPCOUNT * SENSORCOUNT * SENSORDIM,sizeof(int));
int sensordata[SENSORCOUNT*SENSORDIM];
sensordata[7] = 42;  //assign some data 
int (*group3d)[GROUPCOUNT][SENSORCOUNT][SENSORDIM] = groupdata; //<---Here is the problem
group3d[1][5][1] = sensordata[7];  //I want to do this
free(groupdata);
}

In the example above, I want to handle groupdata as group3d temporarily for assignments, and I just cannot seem to wrap myself around the casting. I currently have macros that do the pointer math to enforce the correct structure, but if it was all just in the code, it would be even better when I pass it off. Any suggestions would be greatly appreciated.

note: The 3D cast is to be used in a function way in the bowels of the program. The example is just a minimally viable program for me to try to sort out the code.

3
  • What exactly is the error ? Try using the caste. Why do you create a 3 dimensional array dynamically ? instead allocating memory to an int * ? Commented Mar 14, 2019 at 15:43
  • @Mazhar The array is allocated a int * but is passed around, and a function way in the depths would be served by a 3D cast. The error, which makes sense, is main.c:11:7: warning: incompatible pointer types initializing 'int (*)[16][6][3]' with an expression of type 'int *' Commented Mar 14, 2019 at 15:52
  • Yes, this is what's expected. You are assigning an int (*)[16][6][3] a simple int *. Or more specifically, group3d has type int (*)[16][6][3] while groupdata has type int *. So you can't assign that directly. Though you can use the cast. In your case, if you allocate group3d directly as 3D array, you still can pass this single pointer to other functions just like you were passing the groupdata but this time you won't have to worry about the dimensions. Moreover, group3d is a single pointer with size of regular pointer. It is not any 3d array of pointers. Commented Mar 14, 2019 at 16:10

3 Answers 3

1

When group3d is defined with int (*group3d)[GROUPCOUNT][SENSORCOUNT][SENSORDIM], then *group3d is a three-dimensional array. That would let you use it with (*group3d)[1][5][1].

To use it with group3d[1][5][1], you need group3d to be a pointer to a two-dimensional array:

int (*group3d)[SENSORCOUNT][SENSORDIM] = (int (*)[SENSORCOUNT][SENSORDIM]) groupdata;

(There are some technical concerns about C semantics in aliasing an array of int as an array of array of array of int, but this is not a problem in common compilers with default settings. However, it would be preferable to always use the memory as an array of array of array of int, not as an array of int.)

Sign up to request clarification or add additional context in comments.

1 Comment

From your comments, it's probably better to just use my macros to do the pointer math then? I was assuming that the compiler would be more reliable doing the mathematics.
1
  int l = 5, w = 10, h = 15;
  int Data = 45;
  int *k = malloc(l * w * h * sizeof *k);
  // not use this k[a][b][c] = Data;
  //use this is right
   k[a*l*w + b*l + c] = Data;

Comments

0

In the example above, I want to handle groupdata as group3d temporarily for assignments, and I just cannot seem to wrap myself around the casting.

One possible solution is to create a multidimensional array dynamically like this. This way you won't have to cast things or worry about the dimensions.

int (*group3d)[GROUPCOUNT][SENSORCOUNT][SENSORDIM] = calloc(1, sizeof(int [GROUPCOUNT][SENSORCOUNT][SENSORDIM]));

(*group3d)[1][5][1] = sensordata[7];  //I want to do this

/* Then you can print it like */
printf("%d\r\n", (*group3d)[1][5][1]);

2 Comments

This will fail horribly—there will be no error message but *group3d[1][5][1] will access the wrong memory; it should be (*group3d)[1][5][1]. And it is not what the question requests; the question requests that access to an element be in the form group3d[1][5][1], not *group3d[1][5][1] or (*group3d)[1][5][1].
Thanks for pointing out the problem. Though I have checked that it is wokring.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.