For C89 and earlier, the array dimensions in an array declaration must be constant expressions, meaning they must be evaluable at compile time (numeric constants, sizeof
expressions, expressions involving numeric constants and/or sizeof
expressions, or macros that expand to any of the previous).
C99 introduced "variable-length arrays", where array dimensions determined using runtime expressions (which places some restrictions on where VLAs may be used):
int blocks = some_value();
int seg = some_other_value();
int memory[blocks][segs];
Unfortunately, Microsoft's Visual Studio implementation does not support variable-length arrays (or much else beyond C89).
So, you have a choice - you can either use a different compiler that supports C99 or later (such as MinGW), or you will need to use dynamic memory allocation. If you want to keep BLOCKS
constant but SEG
variable, you would need to do something like this:
int *memory[BLOCKS];
int seg;
...
scanf( "%d", &seg );
...
for ( int i = 0; i < BLOCKS; i++ )
{
memory[i] = malloc( sizeof *memory[i] * seg );
if ( !memory[i] )
// handle memory allocation failure
}
When you're done, you'll need to free
that memory:
for ( int i = 0; i < BLOCKS; i++ )
free( memory[i] );
The main drawback to this method is that the rows of the array won't be contiguous in memory - there will be a gap between memory[i][seg-1]
and memory[i+1][0]
. If that matters, you may have to allocate memory as a single block, then fake 2D indexing:
int *memory = malloc( sizeof *memory * BLOCKS * seg );
if ( !memory )
// handle memory allocation failure
...
memory[i * BLOCKS + j] = some_value();
EDIT
Here’s an (untested!) example based on the snippet in your question - you’re trying to read a .csv file with a fixed number of rows (BLOCKS
) and a variable number of columns (SEG
):
#include <stdio.h>
#include <stdlib.h>
#define BLOCKS 20
int *memory[BLOCKS];
int main( void )
{
int seg;
FILE *stream = fopen( “file.csv”, “r” );
if ( !stream )
// print error and exit
printf( “Please enter a number: “);
if ( scanf( “%d”, &seg ) != 1 )
// print error and exit
for ( size_t b = 0; b < BLOCKS; b++ )
{
/**
* Allocate memory for a block (row)
*/
memory[b] = malloc( sizeof *b * seg );
if ( !memory[b] )
// print error and exit
/**
* Read that row from the file - since it has
* a .csv extension, I am assuming it is
* comma-delimited. Note that malloc is not
* required to initialize memory to any specific
* value - the initial value of each memory[b][s]
* is indeterminate.
*/
for ( size_t s; s < seg; s++ )
if ( fscanf( stream, “%d%*c”, &memory[b][s] )) != 1 )
// print error and exit
}
fclose( stream );
/**
* Do stuff with memory here
*/
/**
* After you’re done with memory, free it
*/
for ( size_t b = 0; b < BLOCKS; b++ )
free( memory[b] );
return EXIT_SUCCESS;
}