2009-10-31 2 views
3

Я недавно пробовал этот эксперимент, в котором вместо перехода на динамическое выделение памяти для требований к памяти неизвестного размера я сделал статическое распределение. Когда массив 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 разрешает это?
+0

Какие варианты не так использовать, чтобы скомпилировать это? Что вы видели, когда вы это использовали? Вы должны попытаться распечатать строку, на которую указывает указатель c. –

ответ

1

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

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

9

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

Посмотрите here для более подробного объяснения в другом вопросе StackOverflow.

0

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

11

Является ли такая операция законной?

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

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

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

С НКУ:

$ 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 позволяют это

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

+0

ISO C99 был принят ANSI в 2000 году - нет такой вещи, как ANSI C99 – Christoph

+0

Существует также «нет такой вещи», как ISO C99 - она ​​называется ISO/IEC 9899: 1999. ANSI C99 - это версия C, стандартизованная в 1999 году, обычно называемая C99, которая была принята ANSI. –

0

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

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

Ошибка здесь. Этот код может выйти из строя, если i слишком большой.

0

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

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

Ссылка: _malloca

 Смежные вопросы

  • Нет связанных вопросов^_^