C: состояние памяти во время объявления массива - PullRequest
4 голосов
/ 23 февраля 2012

Я недавно представил небольшую программу для задания, в которой были следующие две функции и основной метод:

 /** 
  *  Counts the number of bits it
  *  takes to represent an integer a
  */
   int num_bits(int a)
   {
      int bitCount = 0;

      while(a > 0)
      {
         bitCount++;
         a = a >> 1; //shift to the right 1 bit
      }

      return bitCount;
    }

  /**
   * Converts an integer into binary representation
   * stored in an array
   */
   void int2bin_array(int a, int *b)
   {
      //stopping point in search for bits
      int upper_bound = num_bits(a);

      int i;
      for(i = 0; i < upper_bound; i++)
      {
         *(b+i) = (a >> i) & 1; //store the ith bit in b[i]
      }
   }

int main()
{
   int numBits = num_bits(exponent);
   int arr[numBits];     //<- QUESTION IS ABOUT THIS LINE 
   int2bin_array(exponent, arr);

   //do some operations on array arr
}

Когда мой инструктор возвратил программу, он написал комментарий о помеченной мной строке.Выше говорилось, что, поскольку значение numBits неизвестно до времени выполнения, инициализация массива размером numBits является опасной операцией, поскольку компилятор не будет знать, сколько памяти выделить массиву arr.

Мне было интересно, может ли кто-нибудь:

1) убедиться, что это опасная операция

2) объяснить, что происходит с памятью, когда я инициализирую такой массив,как компилятор знает, какую память выделить?Есть ли способ определить, сколько памяти было выделено?

Будем благодарны за любые входные данные.

Ответы [ 2 ]

2 голосов
/ 23 февраля 2012

Это массив переменной длины C99.Он выделяется во время выполнения (не компилятором) в стеке и в основном эквивалентен

 char *arr = alloca(num_bits);

В этом случае, поскольку вы можете знать верхнюю границу функции, и она относительно мала,вам лучше всего использовать

 char arr[sizeof(int)*CHAR_BIT]; 

Этот массив имеет размер, известный во время компиляции, всегда будет соответствовать всему, что вам нужно, и работает на платформах без поддержки C99.

2 голосов
/ 23 февраля 2012

Все должно быть в порядке, оно просто пойдет по стеку.
Единственная опасность - вырвать стек.

malloc будет нормальным способом, тогда вы знаете, если у вас достаточно памяти илинет и может принимать обоснованные решения о том, что делать дальше.Но во многих случаях можно предположить, что вы можете помещать в стек не слишком большие объекты.

Но, строго говоря, если у вас недостаточно места, это плохо провалится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...