Can I make a dynamic array this way?

So my code is this:

int a, b;
printf("Give dimensions\n");
scanf("%d %d", &a, &b);
double array1[a][b];
printf("Give values\n");
int i, j;
for(i=0; i<a; i++)
{
    for(j=0; j<b; j++)
    {
        scanf("%lf", &array1[i][j]);
    }
}

My problem is that they tell me that this is the wrong way to allocate memory and that I should use malloc. I had to create a dynamic array using custom sizes.

Edit: rest of program:

double sum=0;
for(i=0; i<a; i++)
{
    for(j=0; j<b; j++)
    {
        sum = sum + array1[i][j];
    }
    printf("Line %d: sum = %lf\n", i+1, sum);
    sum=0;
}
+4
source share
4 answers

Depending on how you define "correct." It is legal C with C99.

, a b , . , malloc. . , , .

, :

double (*array)[b] = malloc(sizeof(double[a][b]));

, VLA , a[i][j] .

+6

, , / , .

, C99, ​​ C11.

VLA - -

  • VLA . VLA , , --malloc.
  • VLA , .
+5

C , C11 VLA .

, , , . malloc/calloc:

double (*array1)[b] = malloc(a * sizeof(*array1));
if (!array1) {
     // handle allocation failure
}
+4
scanf("%d %d", &a, &b);
double array1[a][b];

C99, ( , , , , , ..).

array1 - (VLA), C99. C2011, , . , __STDC_NO_VLA__ - , VLA.

size_t a, b;
if ( scanf( "%zu %zu", &a, &b ) < 2 )
  // bail out with an error message

#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L && !defined( __STDC_NO_VLA__ ) 

  /**
   * This implementation supports VLAs.  We need to do an additional
   * sanity check on a and b to make sure we don't allocate an
   * object too large for the stack (even though VLAs
   * don't have to be allocated on the stack, that how many 
   * implementations choose to do it).
   */
  if ( a > SOME_MAX_LIMIT || b > SOME_MAX_LIMIT )
    // bail out with an error
  double array1[a][b];

#else  

  /**
   * This implementation does not support VLAs, so we'll have to use
   * dynamic memory allocation.  Note that memory allocated this way
   * is *not* contiguous - rows are not adjacent, so the object immediately
   * following array1[0][b-1] is not array1[1][0].  If that matters, 
   * then this won't work.  
   */
  double **array1 = malloc( sizeof *array1 * a );
  if ( array1 )
  {
    size_t i;
    for ( i = 0; i < a; i++ )
    {
      array1[i] = malloc( sizeof *array1[i] * b );
      if ( !array1[i] )
        break;
    }
    if ( i < a ) // memory allocation failure, clean up any previously allocated memory
    {
      while ( i-- )
        free( array1[i] );
      free( array1 );
      // bail out with an error here
    }
  }
  else
    // memory allocation failed, bail with an error

#endif

array1[i][j], , . :

#if !defined( __STDC_VERSION__ ) || __STDC_VERSION__ < 199901L || defined( __STDC_NO_VLA__ )

  for ( size_t i = 0; i < a; i++ )
    free( array1[i] );

  free( array1 );

#endif

, malloc.

VLA , auto () - , .

, ( ), static, struct union.

VLA :

size_t a, b;
if ( scanf( "%zu %zu", &a, &b ) < 2 )
  // bail out with an error

double (*array1)[b] = malloc( sizeof *array1 * a );

You get a dynamically distributed 2D array with user-defined dimensions that are contiguous, and you are limited only by the size of the heap, not the size of the stack, so you can select large objects this way.

+2
source

Source: https://habr.com/ru/post/1667263/


All Articles