Динамическое распределение памяти в стеке - PullRequest
5 голосов
/ 31 октября 2009

Я недавно попробовал этот эксперимент, в котором вместо динамического выделения памяти для требований памяти неизвестного размера я сделал статическое распределение. Когда я объявил массив a[i], я сохранил переменную i (размер массива) в зависимости от входных данных, которые дает пользователь.

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <conio.h>
 void function(int );
 int main(void)
 {
     int i;
     printf("Enter:");
     scanf("%d",&i);
     function(i);
     printf("i = %d\n",i);
     getch();
     return 0;
 }
 void function(int i)
 {
      char a[i];
      char b[4];
      strncpy(a,"hello",i);
      strcpy(b,"world");
      int j = 0;
      char *c = a;
      for( j = 0; j< 20; j++ )
           printf("%c",*c++);
 }

Мои вопросы:

  • Законна ли такая операция?
  • Если нет, почему компилятор не выдает никаких предупреждений или ошибок?
  • Где будет выделена эта память: стек или куча?
  • Почему ANSI C / GCC позволяет это?

Ответы [ 6 ]

14 голосов
/ 31 октября 2009

Законна ли такая операция?

Он называется массивом переменной длины.

VLA допустимы в ANSI C99 и являются дополнением к некоторым компиляторам до C99. GCC поддерживает его как строгий C99, так и как расширение кода не-C99. Это также допустимо в C ++ 0x.

Если нет, почему компилятор не выдает никаких предупреждений или ошибок?

С gcc:

$ gcc -std=c89 src/vla.c  -Wall -ansi -pedantic
src/vla.c: In function ‘function’:, not dynamic array.
src/vla.c:17: warning: ISO C90 forbids variable length array ‘a’
src/vla.c:21: warning: ISO C90 forbids mixed declarations and code

Наличие conio.h из MSDOS указывает на то, что вы, вероятно, используете компилятор Microsoft Visual C ++, так что не беспокойтесь об этом. MS работает над тем, чтобы сделать их компилятор более совместимым со стандартом C ++ 0x, но не претендует на то, насколько стандартным является режим компилятора C. Вы спрашиваете, почему слов в испанском диалекте нет в словаре французского.

Где будет выделена эта память: стек или куча?

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

Почему ANSI C / GCC позволяет это

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

10 голосов
/ 31 октября 2009

Это действительно C99 .

Смотрите здесь для более подробного объяснения в другом вопросе StackOverflow.

1 голос
/ 31 октября 2009

Это допустимо, но не все компиляторы поддерживают это. По крайней мере Visual Studio <= 2003 afaik не поддерживает его. </p>

Я бы предположил, что это не Ansi C ++, попробуйте gcc -ansi -pedantic.

0 голосов
/ 13 июля 2010

Динамическое выделение памяти в стеке:

Существует библиотечный вызов _malloca, который динамически распределяет память по программному стеку (очень похоже на то, что malloc делает в Heap)

Ссылка: _malloca

0 голосов
/ 31 октября 2009

Код действителен, но при использовании массивов переменной длины следует помнить одну вещь.

void function(int i)
{
     int a[i];
     .
     .
}

Здесь нет проверки ошибок. Этот код может потерпеть неудачу, если i слишком большой.

0 голосов
/ 31 октября 2009

Массивы переменной длины недопустимы в ANSI C (C89). Попробуйте повысить уровень предупреждения вашего компилятора, и я уверен, что вы получите предупреждение / ошибку.

...