Динамически распределенный массив и автоматизация объявленного массива с глобальной областью действия (язык C)

В чем разница между объявлением массива "динамически",

[То есть. с помощью realloc() или же malloc(), так далее... ]

против

объявить массив в main() с глобальной областью действия?,

например.

int main()
{
    int array[10];

    return 0;
}

Я учусь, и на данный момент я чувствую, что между

объявив переменную (массив, что угодно) - с глобальной областью действия,

по сравнению с

динамически размещаемая переменная (массив, что угодно) - И никогда не вызывается free() и позволяя ему быть " уничтоженным " после завершения программы "

Каковы последствия любого варианта?

РЕДАКТИРОВАТЬ

Спасибо за ваши ответы.

Глобальная область видимости должна быть " локальной областью видимости " - локальной для main()

2 ответа

Когда вы объявляете массив как int arr[10] в функции пространство для массива выделяется в стеке. Память будет освобождена при выходе из функции.

Когда вы объявляете массив или любую другую структуру данных, используя malloc() или же realloc()Вы распределили пространство в куче, и память будет освобождена только после выхода из программы. Поэтому, когда программа запущена, вы несете ответственность за ее освобождение с помощью free() после того, как вы больше не хотите его использовать. Если вы не освободите его и не укажете указатель массива на что-то еще, вы создадите утечку памяти. Тем не менее, ваш компьютер всегда сможет восстановить всю использованную память программы после ее завершения из-за виртуальной памяти.

Как kaylum сказал в комментарии ниже вашего вопроса, массив во втором примере не имеет глобальной области видимости. Его сфера ограничена main()и недоступен в других областях, если только main() явно делает его доступным (например, передает его по аргументу другой функции).

Динамическое выделение памяти означает, что программист явно выделяет память при необходимости и явно освобождает ее, когда она больше не нужна. Вследствие этого объем выделяемой памяти может быть определен во время выполнения (например, вычислен на основе пользовательского ввода). Кроме того, если программист забывает освободить память или перераспределяет ее ненадлежащим образом, может произойти утечка памяти (все еще выделяемая программой, но недоступная для программы). Например;

  /*  within a function  */

  char *p = malloc(100);
  p = malloc(200);
  free(p);

утечки 100 байтов, каждый раз, когда этот код выполняется, потому что результат первого malloc() Вызов никогда не освобождается, и тогда он недоступен для программы, потому что его значение нигде не сохраняется.

Ваш второй пример на самом деле представляет собой массив продолжительности автоматического хранения. Что касается вашей программы, она существует только до конца области, в которой она создается. В вашем случае, как main() возвращается, массив перестанет существовать.

Пример массива с глобальной областью видимости

int array[10];

void f() {array[0] = 42;}

int main()
{
      array[0] = 10;
      f();
      /*  array[0] will be 42 here */
}

Разница в том, что этот массив существует и доступен для каждой функции, которая имеет видимость объявления, в том же модуле компиляции.

Еще одно важное отличие состоит в том, что глобальные массивы (обычно) инициализируются нулями - глобальный массив int будет иметь все элементы ноль. Динамически размещенный массив не будет иметь инициализированных элементов (если не создан с calloc(), который инициализируется в ноль). Аналогично, автоматический массив не будет иметь инициализированных элементов. Это неопределенное поведение для доступа к значению чего-либо (включая элемент массива), которое не инициализировано.

Так

 #include <stdio.h>
 int array[10];

 int main()
 {
      int *array2;
      int array3[10];

      array2 = malloc(10*sizeof(*array2));

      printf("%d\n", array[0]);   /* okay - will print 0 */
      printf("%d\n", array2[0]);   /* undefined behaviour.  array2[0] is uninitialised */

      printf("%d\n", array3[0]);   /*  undefined behaviour.  array3[0] uninitialised */

      return 0;
 }

Очевидно, что способ избежать неопределенного поведения состоит в том, чтобы инициализировать элементы массива чем-то допустимым, прежде чем пытаться получить доступ к их значению (например, распечатать их, в приведенном выше примере).

Другие вопросы по тегам