Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.66/29: Рейтинг темы: голосов - 29, средняя оценка - 4.66
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587

С++ VLA и прочее...

30.11.2012, 00:17. Показов 5983. Ответов 51
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
 Комментарий модератора 
Перенесено из Порекомендуйте компилятор


Dev-C++ меня удивляет. Вот такой код компилирует без ошибок и предупреждений:
C++
1
2
3
4
5
6
7
int main()
{
    int m;
    int arr[m];
    
    return 0;
}
А такой и выполняет:
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;
 
int main()
{
    int m;
    cin >> m;
    int arr[m];
    
    return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.11.2012, 00:17
Ответы с готовыми решениями:

Скремблирование и прочее
Добрый день, помогите разобраться. Нужно написать программу для скремблирование файлов. Но перед этим вопрос: как из исходного файла...

Рекурентная формула и прочее
Добрый день , пишу вам для получения помощи! Никак не могу сделать рекурентную формулу и программу под выражением &quot;б&quot;Помогите...

Дирректива define и прочее
Помогите пожалуйста решить задание, никогда раньше с такими не сталкивался! =( 1) Даны целые числа x, у и вещественное число z....

51
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701
30.11.2012, 00:40
Второй код считаю нормальным.
Первый говнокод конечно, но при чём тут IDE? За вывод предупреждений она не ответственна, а то щас наговоришь тут. За предупреждения ответственен компилятор (там стоит gcc). Открываешь в DEV параметры компилятора и пишешь (это нужно уметь делать безусловно) -Wall в опциях и будет круто; в обоих случаях выведутся предупреждения.

В книжке Артура Гриффитса подробно всё описано.
0
 Аватар для Dima_c8
5 / 5 / 2
Регистрация: 17.12.2011
Сообщений: 148
30.11.2012, 00:43
кстати вроде по теме а как там в деве запустить функцию InitCommonControls а то не работает
0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.11.2012, 01:03  [ТС]
Цитата Сообщение от kravam Посмотреть сообщение
Второй код считаю нормальным.
Размер статического массива должен быть известен на момент компиляции. Иначе, как под него память выделять?

Цитата Сообщение от kravam Посмотреть сообщение
Открываешь в DEV параметры компилятора и пишешь (это нужно уметь делать безусловно)
Особенно начинающему... Научи, где что писать.

Добавлено через 8 минут
Цитата Сообщение от kravam Посмотреть сообщение
Первый говнокод конечно, но при чём тут IDE? За вывод предупреждений она не ответственна, а то щас наговоришь тут. За предупреждения ответственен компилятор (там стоит gcc).
Начинающий не будет возиться с подключением другого компилятора к IDE. Для него это всё - IDE.
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
30.11.2012, 01:23
Цитата Сообщение от alsav22 Посмотреть сообщение
Размер статического массива должен быть известен на момент компиляции. Иначе, как под него память выделять?
Оно преобразует переменную и создает статический массив на момент обращения. А void main по-умолчанию и include "stdafx" какой-то куда лучше. А ведь, пропустив автоматом пункт, где надо убрать галочку (а новичок побоится вмешиваться в дефолтные настройки), абсолютно нормальный код не скомпилится. Не говоря уж о том, что студия пытается везде пропихнуть свои стандарты, пугая списком варнингов типа юзай непереносимое printf_s заместо абсолютно нормального printf. Да, можно довести студию до ума, но это уже разбираясь в настройках. Ну и второй код с VLA (variable length array) не считаю слишком критичным. Уж кто бы говорил о стандартах, так это точно не продукты от Microsoft.
0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.11.2012, 01:35  [ТС]
Цитата Сообщение от MrGluck Посмотреть сообщение
А ведь, пропустив автоматом пункт, где надо убрать галочку (а новичок побоится вмешиваться в дефолтные настройки), абсолютно нормальный код не скомпилится
Поэтому я всем советую создавать пустой проект, там галочки не нужно ставить.
Цитата Сообщение от MrGluck Посмотреть сообщение
Не говоря уж о том, что студия пытается везде пропихнуть свои стандарты
С этим согласен.
Цитата Сообщение от MrGluck Посмотреть сообщение
Уж кто бы говорил о стандартах, так это точно не продукты от Microsoft.
С этим тоже согласен, но насчёт размерности массива, причёт здесь Microsoft? Об этом разговоры здесь были и , если я не прав, пусть поправят, но я так понял, что именно по стандарту размер статического массива должен быть величиной константной, а значит известной на момент компиляции.
0
 Аватар для activnaya
256 / 46 / 4
Регистрация: 24.11.2012
Сообщений: 466
30.11.2012, 01:39
alsav22, а что тут собственно не устраивает? память, отведенная под m уже содержит значения, то что кододел ее не инициализировал своим значением, это его проблемы.
C++
1
2
3
4
5
6
7
int main()
{
    int m;
    int arr[m];
    
    return 0;
}
Как заметил MrGluck, VLA даже в Сишке есть. Начиная с Си99 это очень корректный код.
C
1
2
3
4
5
void f(size_t n)
{
    int array[n];
    ...
}
0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.11.2012, 02:52  [ТС]
Вопрос не о том, что кого устраивает или не устраивает. Вопрос о том, как правильно. Как тогда это понимать? http://www.cplusplus.com/doc/tutorial/arrays/
NOTE: The elements field within brackets [] which represents the number of elements the array is going to hold, must be a constant value, since arrays are blocks of non-dynamic memory whose size must be determined before execution. In order to create arrays with a variable length dynamic memory is needed, which is explained later in these tutorials.
Добавлено через 15 минут
Вот эти объяснения, как понимать? Массивы. Статические и динамические
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
30.11.2012, 03:02
alsav22, http://www.open-std.org/JTC1/S... /n1336.pdf
However, an object declared with the static storageclass specifier can have a VM type (that is, a pointer to a VLA type). Finally, all identifiers declared with a
VM type have to be ordinary identifiers and cannot, therefore, be members of structures or unions.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
extern int n;
int A[n]; // invalid file scope VLA
extern int (*p2)[n]; // invalid file scope VM
int B[100]; // invalid file scope but not VM
void fvla(int m, int C[m][m]); // valid: VLA with prototype scope
void fvla(int m, int C[m][m]) // valid: adjusted to auto pointer to VLA
{
typedef int VLA[m][m]; // valid: block scope typedef VLA
struct tag {
int (*y)[n]; // invalid: y not ordinary identifier
int z[n]; // invalid: z not ordinary identifier
};
int D[m]; // valid: auto VLA
static int E[m]; // invalid: static block scope VLA
extern int F[m]; // invalid: F has linkage and is VLA
int (*s)[m]; // valid: auto pointer to VLA
extern int (*r)[m]; // invalid: r has linkage and points to VLA
static int (*q)[m] = &B; // valid: q is a static block pointer to VLA
}
Добавлено через 5 минут
Кстати, на С++, по-моему, даже в С++11 это не по стандарту. Но это тот же сценарий, что и long long int.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701
30.11.2012, 12:11
Цитата Сообщение от alsav22 Посмотреть сообщение
Размер статического массива должен быть известен на момент компиляции. Иначе, как под него память выделять?
А как вообще память под массивы выделяется? Мне кажется функция начинает работать и только тогда выделяется память под массив в стеке. Скорее всего просто указатель на верхушку стека просто-напросто уменьшается на нужное количество байт (в данном случае на m байт). Всё память выделена. ВО ВРЕМЯ РАБОТЫ ФУНКЦИИ main. Проверить так это ли нет- в отладчике сложно. Но можно в том же отладчике посмотреть, откуда функция берёт элементы массива (хотя тут m известно на начало работы, но это не главное, главное, ГДЕ ВЫДЕЛЯЕТСЯ ПАМЯТЬ ПОД МАССИВ)

C++
1
2
3
4
5
6
7
8
#include <stdio.h>
int main()
{
    int m= 0X100;
    int arr[m];
    printf ("%d\n", arr [0]); 
    return 0;
}
А выделяется она в стеке; и она может выделиться так, а может выделиться эдак. Отсюда вывод: выделяется она во время работы функции. И следующий вывод: поэтому ничто (кроме больших размеров) не мешает тому, чтобы размер массива (величина стека, выделенного под него) был определён во время работы функции.

Цитата Сообщение от alsav22 Посмотреть сообщение
Особенно начинающему... Научи, где что писать.
Я уже научил. Уже можно по тому, что я сказал, найти настройки компилятора и место, где прописывать опции, DEV компактна довольна. Там негде особо блудить.
И ещё научу, надо будет. Скажем так: и там и там начинающий сталкивается с определёнными трудностями. Так по мне пусть он лучше некорректным кодом пропишет память (а рано или поздно он всё равно это сделает) и научится, как этого избегать (твой первый код), чем увидит чудо-юдо-рыбу-кит например: strcpy_s, которая ни в одном учебнике по C не упоминается.

Цитата Сообщение от alsav22 Посмотреть сообщение
Начинающий не будет возиться с подключением другого компилятора к IDE. Для него это всё - IDE.
Ну и пусть работает с тем, что дают, а подключает ПОТОМ, когда станет неначинающим.
0
Антикодер
Эксперт функциональных языков программирования
1888 / 870 / 48
Регистрация: 15.09.2012
Сообщений: 3,088
30.11.2012, 12:21
+1 голос за gcc в линухе, на Gentoo библиотеки ставятся автоматически системой портов, что уменьшает количество проблем при их подключении.
0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.11.2012, 20:15  [ТС]
Цитата Сообщение от kravam Посмотреть сообщение
Мне кажется функция начинает работать и только тогда выделяется память под массив в стеке
Неправильно кажется. Память в стеке, под переменные, выделяется до начала работы main(). В этом всё и дело. Как выделить память, если размер её неизвестен?
Миниатюры
С++ VLA и прочее...  
0
 Аватар для activnaya
256 / 46 / 4
Регистрация: 24.11.2012
Сообщений: 466
30.11.2012, 20:19
Цитата Сообщение от alsav22 Посмотреть сообщение
Память в стеке, под переменные, выделяется до начала работы main().
да ну, а stack overflow придумали троли
0
545 / 344 / 12
Регистрация: 05.11.2010
Сообщений: 1,076
Записей в блоге: 1
30.11.2012, 20:21
Второй код считаю нормальным.
Ты может и считаешь, а стандарт C++ - нет.
0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.11.2012, 21:23  [ТС]
Цитата Сообщение от MrGluck Посмотреть сообщение
owever, an object declared with the static storageclass specifier can have a VM type (that is, a pointer to a VLA type). Finally, all identifiers declared with a
VM type have to be ordinary identifiers and cannot, therefore, be members of structures or unions.Код C++

extern int n;
int A[n]; // invalid file scope VLA
extern int (*p2)[n]; // invalid file scope VM
int B[100]; // invalid file scope but not VM
void fvla(int m, int C[m][m]); // valid: VLA with prototype scope
void fvla(int m, int C[m][m]) // valid: adjusted to auto pointer to VLA
{
typedef int VLA[m][m]; // valid: block scope typedef VLA
struct tag {
int (*y)[n]; // invalid: y not ordinary identifier
int z[n]; // invalid: z not ordinary identifier
};
int D[m]; // valid: auto VLA
static int E[m]; // invalid: static block scope VLA
extern int F[m]; // invalid: F has linkage and is VLA
int (*s)[m]; // valid: auto pointer to VLA
extern int (*r)[m]; // invalid: r has linkage and points to VLA
static int (*q)[m] = &B; // valid: q is a static block pointer to VLA
}
MrGluck, не могли бы вы хоть как-то прокоментировать эту цитату. Для меня, как начинающего, сложно понять о чём тут речь.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701
30.11.2012, 21:36
Пришла пора расставить всё на свои места.

Цитата Сообщение от alsav22 Посмотреть сообщение
Неправильно кажется. Память в стеке, под переменные, выделяется до начала работы main(). В этом всё и дело. Как выделить память, если размер её неизвестен?
посмотрел твою цитату; кто такое пишет ему руки надо оторвать, цитату можно понимать двояко (а нужно чтобы она понималась ОДНОЗНАЧНО).

Давай всё-таки разделим мухи отдельно, котлеты отдельно. Есть понятие "выделение стека", а есть понятие "выделение памяти в стеке."На самом деле по твоей цитате речь идёт первом, то есть программе выделяется кусок памяти и говорится: "это стек, запихивай туда свои данные". Иначе и быть не может. Но можно предположить и второй вариант (мою версию выделения памяти)- так уж она скользко написана.

Цитата Сообщение от alsav22 Посмотреть сообщение
Как выделить память, если размер её неизвестен?
Это если предполагать, что память под локальные переменные выделяется до начала main (твои предположения);а если она выделяется в процессе main, то всё становится на свои места.

Поэтому смотрим своими глазами где что и как выделяется, поехали:


Проверяем, вот код:
C++
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
using namespace std;
 
int main()
{
    int m= 0X5555666;
    printf ("%x\n", m);
    getchar ();
    return 0;
}
Так ты говоришь, память под переменную m выделится до начала main? запускаем прогу в отладчике, вот на нулевом рисунке ясно показана программа В НАЧАЛЕ РАБОТЫ, в правом нижнем углу СТЕК и я стрелками показал, что в стеке нет НИЧЕГО ПОХОЖЕГО на 0X5555666

Но, может быть, значения нет, а ячейка памяти выделена? Ни фига подобного, трассируем до момента, когда значение 0x55556666 будет занесено в стек, вот эта инструкция (ris_1.), я на неё показываю стрелкой, кроме того мы видим, что стек с начала работы охренительно увеличился и только ПОСЛЕ ВЫПОЛНЕНИЯ ЭТОЙ ИНСТРУКЦИИ в стек будет положено значение 0X5555666; куда именно я указал пятью восклицательными знаками.

Ну и наконец последняя картинка (ris_2) это мы видим что по адресу в стеке 0X22ff4C РЕАЛЬНО положилось значение 0X5555666 и случилось это непосредственно перед вызовом printf, а далеко не перед началом работы main; ну то есть вышло так: сперва выделена ячейка памяти, через некоторое время (не сразу) туда занесено значение 0X5555666
Миниатюры
С++ VLA и прочее...   С++ VLA и прочее...   С++ VLA и прочее...  

0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.11.2012, 22:54  [ТС]
Цитата Сообщение от kravam Посмотреть сообщение
Так ты говоришь, память под переменную m выделится до начала main?
Это не только я говорю, и не один я говорю. Многие говорят. Не раз, и не два встречал. Например, здесь: Размер статического массива
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701
30.11.2012, 23:27
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Место под все локальные переменные выделяется перед выполнением кода функции. Сколько этого места понадобится
А чё сказать? Я показал на пальцах, что место под локальную переменную m выделилось В ПРОЦЕССЕ выполнения кода, а не перед. Но чел убеждён что "перед". Ну пусть так и будет, мне-то что.

Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
когда его инициализировать, решает компилятор
с этим согласен

Добавлено через 9 минут
НЕ поленился щас вот такой код глянуть:
C++
1
2
3
4
5
6
#include <stdio.h>
int main()
{
    char arr[]= "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr";
    return 0;
}
Да. Всё так и есть. В начале main стек мал и пуст. А где-то в середине программы стек УВЕЛИЧИЛСЯ и перегоняет туда эту строку. (Ставил нардварный бряк на этой строке в секции данных и смотрел, когда к ней будет обращение); могу скриншоты скинуть.
0
01.12.2012, 00:04

Не по теме:

C++
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
using namespace std;
 
int main()
{
    int m= 0X5555666;
    printf ("%x\n", m);
    getchar ();
    return 0;
}
Большой знаток C++ пришел :-D
using namespace std; и ни одного C++ заголовка.

0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
01.12.2012, 00:05
А ничего, что в стеке хранятся не только записи активаций функций, а и вагон с тележкой другой лабуды вроде записей активаций системных вызовов и SEH-фреймов, и кто-то должен за ними убирать, чтобы user-функции не напоролись на то, что им видеть не положено?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.12.2012, 00:05
Помогаю со студенческими работами здесь

Указатель на массив char и прочее
Страуструп для проверки прочитанного в заданиях после одной из глав просит через typedef сделать пару объявлений и вот как делать некоторые...

Класс, конструктор, деструктор и прочее
Добрый день. Есть задание: Написать программу работы с матрицами (матрица представляет собой двумерный массив). Матрица является...

ООП Язык С Конструкторы и прочее
Текст задания: (ну хоть убейте, но не понимаю). Если не целый код, то хоть ссылки на похожее, на примеры, гугл не помогает Создайте...

Стиль написания кода(читабельность и прочее)
Недавно делал тестовое задание для поиска работы, но мне сказали, что код не совсем корректно написан. Задание:Написать рекурсивный и не...

Размер примитивных типов, выравнивание и прочее
Как обычно борются с тем, что примитивный тип от компа к компу разного размера? Допустим, если записывают данные по сети или в двоичные...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru