I've got a school project where I have to create a game with a bi dimensional array where the rows and columns will change. So what I want to do is asking to user what's the number of rows and the number of columns and then create the game board. So if the user says 6 rows and 10 columns I'll save it in two variables and then I'll create the bi dimensional array. The problem here is that Visual Studio said that I've got to have constant values, there's a way to make a bi-dimensional array without constants? Thanks for the help.
-
2Read about *pointers* and *`malloc`*. – Some programmer dude May 22 '14 at 12:02
-
1You can dynamically allocate the appropriate memory, and access the parts of the board with with row and column coordinates, but multiplying the row by rowsize (which the user would have entered and have been stored in a variable). – AntonH May 22 '14 at 12:02
-
Refrain from answering or hinting at answers in comments - that is not what comments are for, If you have an answer, post it. http://stackoverflow.com/help/privileges/comment – Clifford May 22 '14 at 20:33
3 Answers
With your compiler, you have to use malloc to allocate your array. Although C99 supports the int[x][y]
Syntax when x
or y
are not compile-time constant, Visual Studio does not.
Allocate your array like this:
int* ar = malloc(sizeof(int) * x * y);
Then you can use it like this:
int getIndex(int* array, int col, int row){
return ar[row*y+col];
}
Of course, you have to store the y
somewhere so that you can use it for index calculations (as shown in the getInt
example function. For example, you could wrap the int*
pointer to the array and the y
into a struct and always pass around this struct.

- 38,535
- 21
- 92
- 152
-
There is nothing wrong with `int arr[x][y]`, where x and y are runtime variables. There is no real need to use malloc either. – Lundin May 22 '14 at 12:08
-
-
-
-
@luidgi27: Yeah, almost forgot about VLAs as I am also using Visual Studio and thus haven't used them for a long time. I have clarified the answer. – gexicide May 22 '14 at 12:25
If you want to use normal array indexing for a dynamic 2d array:
int* array_mem = malloc( sizeof(*array_mem) * x * y ) ;
int** array = malloc( sizeof(*array) * x ) ;
int i = 0;
for( i = 0; i < x; i++ )
{
array[i] = &array_mem[i * y] ;
}
The array
and be indexed as a two dimensional array such as array[0][5]
, and shares the same contiguous memory properties of a normal array. However sizeof(array)
will not return the size of the allocated memory as it would for a normal array.
Note that in this case you are responsible for returning the memory to the heap when done - it does not do that automatically except on termination of the process.
If you have not covered dynamic memory or pointers in class, you may be better off using a simpler alternative solution, such as simply creating an array large enough for the largest dimensions a user will request (and include some range checking on the input).

- 88,407
- 13
- 85
- 165
-
1[A better way to dynamically allocate and access 2D arrays.](http://stackoverflow.com/questions/12462615/how-do-i-correctly-set-up-access-and-free-a-multidimensional-array-in-c) – Lundin May 22 '14 at 12:58
-
@Lundin : Interesting, but still C99 dependent. If VC++ is the chosen courseware at luidgi27's school, debating the wisdom of that or making suggestions he cannot use with it is less than helpful perhaps. – Clifford May 22 '14 at 20:37
-
Pointing out that he is getting taught outdated things that have been obsolete for 15 years is pretty helpful. Meaning he'll have to complete his studies elsewhere, if he is aiming for a C programming career. – Lundin May 23 '14 at 06:28
-
Yes, he should be learning C++. Making all updates to C irrelevant. When I have to use C I stick to C90 because it is closest to a C++ subset. There remain strong and valid reasons for doing that so it is hardly obsolete. Many schools teach C before C++, (perhaps misguidedly); in that context it is simpler not to introduce C code that is not also C++. My point is that there are many good reasons for not following the committee and using every new tool in the bag. – Clifford May 23 '14 at 06:54
You get this answer because you are using a crappy, non-standard compiler. The solution to your problem is to compile your C code on a good compiler instead.
Code such as int arr[x][y];
, where x and y are plain int variables, is perfectly fine.
This is known as a variable-length array (VLA). Visual Studio doesn't know this, because it doesn't follow the C standard.

- 195,001
- 40
- 254
- 396
-
1Not being C99 compliant hardly makes a compiler "crappy" or "non-standard". VC++ applies the C89 standard - so it is not "non-standard", just not "latest standard". Opinions - especially those so violently expressed, should be avoided in answers. – Clifford May 22 '14 at 12:29
-
@Clifford VC++ has poor conformance to C90 as well. It's a C++ compiler if anything, hence the ++. Although Microsoft have problems supporting the C++ standard as well. Furthermore, every other C compiler in the market supports C99 or C11 except Microsoft. If we weren't talking about compilers but lets say a TV from 1990, with a lot of flicker, showing the wrong colors, would you hesitate to label it as crap? – Lundin May 22 '14 at 12:54
-
You can easily test this: `#ifndef __STDC__ #error Crap compiler #endif`. – Lundin May 22 '14 at 13:06
-
Cite a specific C90 non-conformance if you will - especially a serious one? I suggest your assertion is more anti-Microsoft propaganda than considered fact. The compiler supports extensions and deviations (as does GCC), some enabled by default, but Microsoft have a legacy of commercial customers who would not upgrade if the compiler suddenly started refusing to compile their legacy code. And as you say their emphasis going forward is C++, so C support is only relevant to their legacy customers. – Clifford May 22 '14 at 13:08
-
As an embedded systems developer, outside of targets supported by GCC, I see C90 is prevalent, with C99 support, if any restricted to standard library changes. – Clifford May 22 '14 at 13:08
-
I am not sure what testing `__STDC__` proves - especially given that it is defined in VC++ with the `/Za` (Disable Language Extensions) option (citation: http://msdn.microsoft.com/en-us/library/b0084kay.aspx) – Clifford May 22 '14 at 13:19
-
@Clifford `__STDC__` is a good test, because it is the very minimum you can expect from a compiler conforming to ISO 9899:1990 + Amd1 1995. If they can't even get that right, chances are the whole compiler is broken. Just tested with VC++ Express 2013, option `/Za` as stated by Microsoft. Result: `error c1189 Crap compiler`. – Lundin May 22 '14 at 13:42
-
Further playing around for a few minutes, still with `/Za`: `int _Bool;` doesn't compile. `void main (void)` compiles. `//` compiles. I bet if you use this compiler on regular basis, you'd end up with a very long list of non-conformance. – Lundin May 22 '14 at 14:08
-
This is a discussion for another place. void main() is valid C90 - even GCC allows that. I tested __STDC__ in 2013 Express and its fine - I wonder what you did wrong? – Clifford May 22 '14 at 20:05
-
Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/54235/discussion-between-clifford-and-lundin). – Clifford May 22 '14 at 20:05