Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8681659
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T21:34:05+00:00 2026-06-12T21:34:05+00:00

A few days ago I stumbled on a code where an extensive use of

  • 0

A few days ago I stumbled on a code where an extensive use of conversions from pointer to type to pointer to array of type was made to give a bi-dimensional view of a linear vector in memory. A simple example of such a technique is reported below for clarity:

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

void print_matrix(const unsigned int nrows, const unsigned int ncols, double (*A)[ncols]) {  
  // Here I can access memory using A[ii][jj]
  // instead of A[ii*ncols + jj]
  for(int ii = 0; ii < nrows; ii++) {
    for(int jj = 0; jj < ncols; jj++)
      printf("%4.4g",A[ii][jj]);
    printf("\n");
  }
}

int main() {

  const unsigned int nrows = 10;
  const unsigned int ncols = 20;

  // Here I allocate a portion of memory to which I could access
  // using linear indexing, i.e. A[ii]
  double * A = NULL;
  A = malloc(sizeof(double)*nrows*ncols);

  for (int ii = 0; ii < ncols*nrows; ii++)
    A[ii] = ii;

  print_matrix(nrows,ncols,A);
  printf("\n");
  print_matrix(ncols,nrows,A);

  free(A);
  return 0;
}

Given that a pointer to type is not compatible with a pointer to array of type, I would like to ask if there are risks associated with this casting, or if I can assume that this casting will work as intended on any platform.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-12T21:34:06+00:00Added an answer on June 12, 2026 at 9:34 pm

    It is guaranteed that a multidimensional array T arr[M][N] has the same memory layout as a single-dimensional array with the same total number of elements T arr[M * N]. The layout is the same because arrays are contiguous (6.2.5p20), and because sizeof array / sizeof array[0] is guaranteed to return the number of elements in the array (6.5.3.4p7).

    However, it does not follow that it is safe to cast a pointer to type to a pointer to array of type, or vice versa. Firstly, alignment is an issue; although an array of a type with fundamental alignment must also have fundamental alignment (by 6.2.8p2) it is not guaranteed that the alignments are the same. Because an array contains objects of the base type, the alignment of the array type must be at least as strict as the alignment of the base object type, but it can be stricter (not that I’ve ever seen such a case). However, this is not relevant for allocated memory, as malloc is guaranteed to return a pointer suitably allocated for any fundamental alignment (7.22.3p1). This does mean that you cannot safely cast a pointer to automatic or static memory to an array pointer, although the reverse is allowed:

    int a[100];
    void f() {
        int b[100];
        static int c[100];
        int *d = malloc(sizeof int[100]);
        int (*p)[10] = (int (*)[10]) a;  // possibly incorrectly aligned
        int (*q)[10] = (int (*)[10]) b;  // possibly incorrectly aligned
        int (*r)[10] = (int (*)[10]) c;  // possibly incorrectly aligned
        int (*s)[10] = (int (*)[10]) d;  // OK
    }
    
    int A[10][10];
    void g() {
        int B[10][10];
        static int C[10][10];
        int (*D)[10] = (int (*)[10]) malloc(sizeof int[10][10]);
        int *p = (int *) A;  // OK
        int *q = (int *) B;  // OK
        int *r = (int *) C;  // OK
        int *s = (int *) D;  // OK
    }
    

    Next, it is not guaranteed that casting between array and non-array types actually results in a pointer to the correct location, as the casting rules (6.3.2.3p7) do not cover this usage. It’s highly unlikely though that this would result in anything other than a pointer to the correct location, and a cast via char * does have guaranteed semantics. When going from a pointer to array type to pointer to base type, it’s better to just indirect the pointer:

    void f(int (*p)[10]) {
        int *q = *p;                            // OK
        assert((int (*)[10]) q == p);           // not guaranteed
        assert((int (*)[10]) (char *) q == p);  // OK
    }
    

    What are the semantics of array subscripting? As is well known, the [] operation is just syntactic sugar for addition and indirection, so the semantics are those of the + operator; as 6.5.6p8 describes, the pointer operand must point to a member of an array that is large enough that the result falls within the array or just past the end. This is a problem for casts in both direction; when casting to a pointer to array type, the addition is invalid as there does not exist a multidimensional array at that location; and when casting to a pointer to base type, the array at that location only has the size of the inner array bound:

    int a[100];
    ((int (*)[10]) a) + 3;    // invalid - no int[10][N] array
    
    int b[10][10];
    (*b) + 3;          // OK
    (*b) + 23;         // invalid - out of bounds of int[10] array
    

    This is where we start to see actual issues on common implementations, not just theory. Because an optimiser is entitled to assume that undefined behavior does not occur, accessing a multidimensional array through a base object pointer can be assumed not to alias any elements outside those in the first inner array:

    int a[10][10];
    void f(int n) {
        for (int i = 0; i < n; ++i)
            (*a)[i] = 2 * a[2][3];
    }
    

    The optimiser can assume access to a[2][3] does not alias (*a)[i] and hoist it outside the loop:

    int a[10][10];
    void f_optimised(int n) {
        int intermediate_result = 2 * a[2][3];
        for (int i = 0; i < n; ++i)
            (*a)[i] = intermediate_result;
    }
    

    This will of course give unexpected results if f is called with n = 50.

    Finally it’s worth asking whether this applies to allocated memory. 7.22.3p1 specifies that the pointer returned by malloc “may be assigned to a pointer to any type of object with a fundamental alignment requirement and then used to access such an object or an array of such objects in the space allocated“; there’s nothing about further casting the returned pointer to another object type, so the conclusion is that the type of the allocated memory is fixed by the first pointer type the returned void pointer is cast to; if you cast to double * then you can’t further cast to double (*)[n], and if you cast to double (*)[n] you can only use double * to access the first n elements.

    As such, I’d say that if you want to be absolutely safe you should not cast between pointer and pointer to array types, even with the same base type. The fact that layout is the same is irrelevant except for memcpy and other accesses via a char pointer.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

A few days ago I posted this question and everyone suggested me to use
A few days ago I asked about passing a data structure from java to
i have seen a few days ago such problem there is given two array
A few days ago i asked this question: Displaying images from Facebook photo albums
A few days ago, I watched the video tutorial which explains how to use
A few days ago I made a lord generator for a game called Broken
A few days ago I posted some code like this: StreamWriter writer = new
A few days ago I asked a question about returning select fields from a
Here's a question I had stumbled upon a few days ago. The question is
Few days ago I got an newsletter from an company to my Gmail address

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.