3

I can't understand some basic thing in c++ and have been wondering. Please help me. I understand that p points to memory that would be a 2D int matrix of 3x4 size.

int(*p)[3][4];

1) Why can't I allocate memory like following?

p = new int[3][4];

2) It should be like following to work. But why?

p = new int [1][3][4];    //or new int [5][3][4]; etc

3) What does following line of code mean? It is semantically correct but what is it doing? What is significance of empty [] in following line?

p = new int [ ][3][4];
wally
  • 10,717
  • 5
  • 39
  • 72
Pervez Alam
  • 1,246
  • 10
  • 20

2 Answers2

2

c++ is a strongly typed language. int is not the same as int*. Likewise int[3] is not the same type as int*. But just lightly poke int[3] with a stick and it will fall apart and decay to an int*. c++ does this because c does it.


Why can't I allocate memory like following?

p = new int[3][4];

Because the new is returning a pointer to int[4]:

auto p1 = new int[3][4]; // int(*p1)[4]

The array has decayed to a pointer. It has lost the type and first dimension. It would be best to avoid pointers for arrays and stick to using templates and references. Or better yet, prefer std::vector or std::array.

You could have multiple pointers to the same address, but with different types, which can be confusing.


2) It should be like following to work. But why?

p = new int [1][3][4];

In this example the array of int[3][4]s has also decayed to a pointer:

auto p2 = new int [1][3][4]; // int(*p2)[3][4]

So here the value returned by new can be assigned to p because it has the same type. Note however that the pointer type doesn't include information about the size of the array, it only has a type that points to elements which happen to be arrays of a lower dimension (that haven't decayed to pointers).


3) What does following line of code mean? It is semantically correct but what is it doing? What is significance of empty [] in following line?

p = new int [ ][3][4];

This might not always compile, and if it does then it is a compiler extension that will determine the value of the empty square brackets.

Community
  • 1
  • 1
wally
  • 10,717
  • 5
  • 39
  • 72
1

Because in C, "int *p" has two interpretations. You can consider P to be a pointer to a single integer, but it can also be considered to be a pointer to an array of integer.

A common example, strings. char *a = "hello";

"a" is a pointer to a single character, 'h', but more commonly it is treated as a pointer to an array of characters, aka a string.

So, you can do this: char * a = new char[6]; strcpy(a, "hello");

I believe that your third example is not valid C++.

While this: p = new int [9][3][4]; Allocates an array of 9 two dimensional arrays of 3x4.

Try this test:

int test()
{
    int(* p)[3][4] = new int[1][3][4];

    printf("sizeof(p)=%d, sizeof(*p)=%d\n", sizeof(p), sizeof(*p) / sizeof(int));

    size_t q1 = (size_t)&p[0][0][0];
    size_t q2 = (size_t)&p[1][0][0];
    printf("p, diff: %d\n", (q2 - q1) / sizeof(int));

    size_t r1 = (size_t)&p[0][0][0];
    size_t r2 = (size_t)&p[0][1][0];
    printf("p, diff: %d\n", (r2 - r1) / sizeof(int));

    size_t s1 = (size_t)&p[0][0][0];
    size_t s2 = (size_t)&p[0][0][1];
    printf("p, diff: %d\n", (s2 - s1) / sizeof(int));
    return 0;
}
joeking
  • 2,006
  • 18
  • 29