0

How do I assign to a multi dimensional array without casting [][] to **? I have an example below. What I found was How do I declare a 2d array in C++ using new? but that uses int** rather then new int[][4].

#include<cassert>

int a[8][4];
int*b = &a[0][0];
int*c = &a[2][0];
int*d = &a[0][2];

int main() {
    //shows right side is closer
    assert(d-b==2);
    assert(c-b==8); 
    auto aa = new int[][4];
    //set the right side, but is a syntax error
    //aa[][0] = new int[8];
    //type error
    aa[0] = new int[8];
}
Community
  • 1
  • 1
  • 4
    use `vector>` and save yourself a heap of potential problems... – Mats Petersson Sep 10 '13 at 15:50
  • 1
    @MatsPetersson *"a heap of potential problems"* pun intended – Manu343726 Sep 10 '13 at 15:52
  • 1
    not to be 'smart', but when was `new` introduced into C? – KevinDTimm Sep 10 '13 at 15:53
  • @KevinDTimm: I'm too lazy to write the malloc equivalent –  Sep 10 '13 at 15:54
  • "Assign to an array"? Arrays in C++ are not assignable. – AnT stands with Russia Sep 10 '13 at 15:56
  • @AndreyT: So is `int*var[size]` my only option? why the heck is `int var[][size]` legal!?! –  Sep 10 '13 at 15:58
  • @MatsPetersson: This isn't for using. I noticed `int var[][size]` is legal and couldn't figure out how to assign to it –  Sep 10 '13 at 15:58
  • @KevinDTimm have you never heard about the C/C++ language? Its the language developed by the C programmers who have access to a C++ compiler. – Manu343726 Sep 10 '13 at 16:03
  • @KevinDTimm its characterized by the use of `new/delete`as if they were lollipops, and the use of `strlen()` instead of `std::string`, and other C-reinvent-the-weel-every-minute features – Manu343726 Sep 10 '13 at 16:08
  • 1
    @acidzombie24 `int var[][size]` isn't legal. You're just using a broken compiler. You must specify the size of _all_ of the dimensions in a new expression. Otherwise, the compiler doesn't know how many bytes to request. – James Kanze Sep 10 '13 at 16:15
  • @acidzombie24: What your options are depends on what you are trying to do. At this point it is not entirely clear to me. – AnT stands with Russia Sep 10 '13 at 16:24
  • @AndreyT: it's been answered. I was trying to understand why `int[][4]` exist and it happens to be illegal (although my compiler doesnt give me an error as clang/gcc does) and is used for typecast/function params –  Sep 10 '13 at 17:36

3 Answers3

1

Try

int (*array)[4] = (int (*)[4])malloc(sizeof(int) * 8 * 4);

now you can access up to

array[7][3];
Sergey L.
  • 21,822
  • 5
  • 49
  • 75
  • I rather use `int *var[4]; var[0]=new int[10];` instead –  Sep 10 '13 at 15:57
  • 1
    @acidzombie24 then you are in the `int **` scenario, I thought you wanted to avoid that. And you would need to do 4 allocations. `int ** != int (*)[4]` – Sergey L. Sep 10 '13 at 16:00
  • Its more to learn how to use that syntax or why it exist. Normally i use vector or if i must (in C) malloc(sizeof(int)*width*height*dim3*dim4). +1 anyways cause i did say that –  Sep 10 '13 at 16:02
1

You should be getting an error on the line with the new int[][4]. There must be an expression inside the []. Otherwise, how can the compiler know how much to allocate. (Some quick checks with VC++, which erroneously does accept this expression, shows that it treats it as the equivalent of new int[0][4], and allocates 0 bytes. It doesn't compile with g++.)

And of course, you confuse things additionally by abusing auto. The one reason never to use auto is that you don't know the actual type, and auto means you don't have to know it (until you want to use the variable, of course). In this case, you should definitely not use auto, because the type is a bit special, and you want your readers to know it:

int (*aa)[4] = new int[8][4];

Once you see this, it should be obvious that aa[0] has type int[4], and there's no way you can assign a pointer to it, since it isn't a pointer.

Of course, in C++, you'd never write anything like this anyway. You'd define a Matrix2D class, and use it. (And it would probably use a std::vector<int> to get the memory, and calculate the single index from the two you give. Internally, of course, so you don't have to think about it.) There is, in fact, never a case for using array new.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
0

edit: https://stackoverflow.com/a/18723991/598940 indicates a = new int[][8] is actually not legal.

From your comments, are you asking why a = new int[][8] is legal but a[][4] is not?

int[] is a type expression representing the same as the type int*. It exists (I believe) to allow for more descriptive type declarations (perhaps among other things)

void foo(int* x);   // is x an array of ints? or just a pointer to a single one?
void foo(int[] x);  // ah, ok -- x is intended to represent an array of ints

The value expression a[], on the other hand, has no meaning.

Community
  • 1
  • 1
alecbz
  • 6,292
  • 4
  • 30
  • 50
  • 2
    `a = new int[][8]` _isn't_ legal. The only place in C where something like `int [][8]` would be legal is as a function parameter. – James Kanze Sep 10 '13 at 16:16