2

Given is this function

void printMatrix(int *m, int ze, int sp)

Now *m is supposed to be a 2 dimensional array (or more like a pointer to a 2 dimensional array).

So how can I use this *m as m[][] ?

2
  • Can you show an example of initializing the value that will be passed in to m? It's unclear whether you created an actual 2-D array and badly forced it to be interpreted as a 1-D array, or if you actually have a 1-D array that you want to process as a 2-D array. Commented Jan 17, 2017 at 15:45
  • Can you change the function signature? If so, use a VLA. Commented Jan 17, 2017 at 16:12

4 Answers 4

4

Variable-Length Arrays can help you here:

int (*p)[sp] = (void*) m;

Now you can access the elements via p[i][j].

See it live on Coliru

About the well-definedness of the cast with respect to strict aliasing rules: it is valid, because both m and p point to compatible types.

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

7 Comments

Wouldn't it violate the strict aliasing rule?
@EugeneSh. From what I find on cppreference, it is valid. Maybe I'll dig into a copy of the standard later.
Yeah, it looks fine. p is a pointer to array of integers (though the syntax might be confusing), which is surely compatible with a pointer to array of integers :) Update No..wait. Something is not right here.. let me digest it...
Yeah, that's fine, sorry :) My doubt was about what would p[i] point to. Apparently it would point to the ith "row" *(p + sp*sizeof(int))
int(*)[n] and int* are not compatible types, that's not why this is ok. But I believe a pointer-to-type can always be coverted to an array-pointer-to-type without violating strict aliasing. "An object shall have its stored value accessed only by an lvalue expression that has one of the following types:" /--/ "an aggregate or union type that includes one of the aforementioned types among its members". An int array is an aggregate and it includes int among its members.
|
2

You cannot, as m can be dereferenced only once. But if you know the dimensions of the array, you can calculate the 1D index as

element[i][j]=m[i * width + j];

5 Comments

Actually, the computation would make more sense as element[i][j]=m[i * width + j];
Thanks to both of you! :)
Why not simply use memcpy so that you utilize the data cache optimally? This code may or may not do that.
@Lundin I think = means "is expressed as" here, not an actual copy to a new array.
Oh that... Right, @Quentin, that's what is meant here.
2

If m is indeed a pointer to a 2D matrix, you can declare the arguments this way:

void printMatrix(int rows, int cols, int m[rows][cols]) {
    ...
}

Comments

0

You will have to assume that it is a so-called "mangled" array. In which case you can create a new array as a VLA:

void printMatrix(int *m, int ze, int sp)
{
  int array[ze][sp];
  memcpy(array, m, sizeof(int[ze][sp]));
}

Or perhaps as a dynamically allocated 2D array:

void printMatrix(int *m, int ze, int sp)
{
  size_t size = sizeof(int[ze][sp]);
  int (*array)[sp] = malloc(size);
  memcpy(array, m, size);
  ...
}

Converting the int* to an array pointer type is however questionable practice, which will cause pointer aliasing problems. The best is of course if you can rewrite the function prototype to properly use a 2D array instead.

3 Comments

Ok, this is a good answer too (and seems in relation to my topic the most fitting one). Thanks, will try that too
What do you define "mangled array" as? A multidimensional array hidden behind a pointer to its first element?
@Quentin Yes, something like that was often used in older C programs, since they didn't have pointers to VLAs. Typically you would do int* array = malloc(x*y*sizeof(int))

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.