Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 4.88
Bers
Заблокирован
#1

хитрая константа не даёт создать обычный массив - C++

25.11.2011, 18:47. Просмотров 3227. Ответов 64
Метки нет (Все метки)

Почему я не могу создать обычный массив, указав константу в качестве количества элементов?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int n=10;
const int N(n); //N вроде как константа 
                     //действительно получает значение 10
 
 
int A[N]; //error C2057: требуется константное выражение
             //error C2466: невозможно выделить память 
             //для массива постоянного нулевого размера
 
int main()
{
   int b= N; //b получает корректное значение 10
   const int c=N; //с получает корректное значение
   return 0;
};
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.11.2011, 18:47
Здравствуйте! Я подобрал для вас темы с ответами на вопрос хитрая константа не даёт создать обычный массив (C++):

Можно ли создать проект не managed c++, а обычный c++, но с формами в VS2008? - C++
Можно ли создать проект не managed c++, а обычный c++, но с формами в VS2008?

Перевести обычный массив в векторный - C++
#include <iostream> #include <stdlib.h> #include <math.h> #include <time.h> using namespace std; int main() { int min =...

Как из массива значений цветов создать обычный PNG файл? - C++
Подскажите, знающие люди, как из массива значений цветов (для каждого пикселя) создать обычный PNG файл. Сколько не колесил по интернету...

Скопировать элементы Vector в обычный массив - C++
Вобщем есть поля класса * arr // массив size // размер массива max_size //максимальный размер массива vector <Model> lst; ...

Как создать обычный файл exe, который могут открывать друзья. - C++
Всем доброе утро! Вопрос о том как сделать программу, которая запускалась бы одним файлом .exe. Создал программу (ну самую простейшую)....

Почему матрица выводится как обычный массив - C++
//matriza.h #pragma once class matriza { float *b,max,s; int n,m,nom; public: matriza(); void ww_matriza();

64
go
Эксперт С++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
25.11.2011, 20:26 #31
delete
0
prazuber
110 / 110 / 3
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 20:28 #32
go, и? Не понимаю смысла сообщения.
1
Chelioss
180 / 180 / 4
Регистрация: 08.01.2011
Сообщений: 1,133
25.11.2011, 20:31 #33
Что значит вообще "выделяется память"?
При компиляции создается программа и она занимает место на диске. Массив будет содержатся в этом месте? Нет.
А где? Выделяется память в той памяти, которая дает операционная система при запуске приложения? Но ведь это уже после компиляции, а не во время.
0
prazuber
110 / 110 / 3
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 20:37 #34
Да, я неудачно выразился. Память не выделяется на этапе компиляции. Но на этапе компиляции уже известно, сколько памяти надо будет выделить.
Цитата Сообщение от Сыроежка Посмотреть сообщение
компилятор должен сгенерировать объектный код, который должен передвинуть указатель стека на конкретное количество байт при входе в функцию.
Если же массив задан динамически, то компилятор о его размере ничего не знает.

Добавлено через 1 минуту
Одни массивы (те, размер которых известен на этапе компиляции) создаются в стеке, сразу при входе в функцию. Другие - - в куче, и они уже создаются тогда, когда до них дойдет выполнение программы.
1
Chelioss
180 / 180 / 4
Регистрация: 08.01.2011
Сообщений: 1,133
25.11.2011, 20:38 #35
Цитата Сообщение от PraZuBeR Посмотреть сообщение
компилятор должен сгенерировать объектный код, который должен передвинуть указатель стека на конкретное количество байт при входе в функцию.
А почему это нельзя сделать во время выполнения? Не компилятором, конечно, а самой программой?
0
Сыроежка
Заблокирован
25.11.2011, 20:38 #36
Цитата Сообщение от PraZuBeR Посмотреть сообщение
Да, я неудачно выразился. Память не выделяется на этапе компиляции. Но на этапе компиляции уже известно, сколько памяти надо будет выделить.

Если же массив задан динамически, то компилятор о его размере ничего не знает.
Я не поинмаю, причем здесь "динамически," когда речь идет об объявлении массивов?! Нет такого типа в С++ как "динамический массив". Так что не надо говорить о том, что к вопросу никакого отношения не имеет.
1
prazuber
110 / 110 / 3
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 20:40 #37
Сыроежка, под "динамическим массивом" я понимаю конструкцию
C++
1
T* a = new T[n]
1
Сыроежка
Заблокирован
25.11.2011, 20:46 #38
Цитата Сообщение от PraZuBeR Посмотреть сообщение
Сыроежка, под "динамическим массивом" я понимаю конструкцию
C++
1
T* a = new T[n]
Вы что угодно можете под этим понимать, но исходная тема совершенно о другом!
1
prazuber
110 / 110 / 3
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 20:49 #39
На сабж темы я уже ответил. Это полемика, вызванная вопросом
Цитата Сообщение от Chelioss Посмотреть сообщение
Почему размер массива должен быть известен на этапе компиляции? Ведь память выделяется под массив во время выполнения как и для new T[size].
И вообще зачем такое сделали?
И прошу пожалуйста линк, где я говорил фразу "к вопросу никакого отношения не имеет".
1
Bers
Заблокирован
25.11.2011, 20:57  [ТС] #40
Цитата Сообщение от PraZuBeR Посмотреть сообщение
Одни массивы (те, размер которых известен на этапе компиляции) создаются в стеке,
C++
1
2
3
4
int A[100]; //живет в куче, а не на стеке.
//хотя его размер так же должен быть известен на этапе компиляции.
 
int main(){   return 0;};
0
GhostVIRUS
6 / 6 / 0
Регистрация: 17.09.2011
Сообщений: 81
25.11.2011, 21:06 #41
Почему то я так не думаю. Т.к. для компилятора переменная - переменная, а константа - константа.
1
Bers
Заблокирован
25.11.2011, 21:13  [ТС] #42
А вот этот эксперимент наглядно показывает, что компилятор делает принципиальное различие между константами времени компиляции и всеми прочими:


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template<const int Size> struct Test{  int A[Size];};
 
struct T2
{
    T2():a(333){}
    const int Get() { return a;}
    int a;
};
 
int main()
{
   T2 rrrr;
   
   Test<sizeof(int)> t; //можно
  
   Test<rrrr.Get()> t1; 
 //error C2975: Size: недопустимый аргумент шаблона для "Test", 
 //требуется константное выражение времени компиляции
   return 0;
};
0
Сыроежка
Заблокирован
25.11.2011, 21:21 #43
Цитата Сообщение от Bers Посмотреть сообщение
C++
1
2
3
4
int A[100]; //живет в куче, а не на стеке.
//хотя его размер так же должен быть известен на этапе компиляции.
 
int main(){   return 0;};
Увы, вы заблуждаетесь! Этот массив не "живет" в куче. Он объявлен в статической области памяти программы, которая инициаизируется до входа в main. А память под названием куча - это совсем другое!
1
Bers
Заблокирован
25.11.2011, 21:23  [ТС] #44
Цитата Сообщение от Сыроежка Посмотреть сообщение
Увы, вы заблуждаетесь! Этот массив не "живет" в куче. Он объявлен в статической области памяти программы, которая инициаизируется до входа в main. А память под названием куча - это совсем другое!
В чем принципиальное отличие статической области памяти от кучи?
1
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
25.11.2011, 21:25 #45
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Bers,
C++
1
2
3
4
int Array[100]; //живет в куче, а не на стеке.
//хотя его размер так же должен быть известен на этапе компиляции.
 
int main(){   return Array[0];};
Bash
1
2
3
alexxx@alexxx-laptop:~/c++$ g++ -g 2.cpp 
alexxx@alexxx-laptop:~/c++$ readelf -a a.out | grep Array
    59: [B]0804a040[/B]   400 OBJECT  GLOBAL DEFAULT   26 Array
Bash
1
2
alexxx@alexxx-laptop:~/c++$ objdump -d a.out > dump
alexxx@alexxx-laptop:~/c++$ less dump
Bash
1
2
3
4
5
6
7
8
08048494 <main>:
 8048494:       55                      push   %ebp
 8048495:       89 e5                   mov    %esp,%ebp
 8048497:       a1 40 a0 04 08          mov    0x804a040,%eax
 804849c:       5d                      pop    %ebp
 804849d:       c3                      ret    
 804849e:       90                      nop
 804849f:       90                      nop
в данном случае массив выделен на момент компиляции, ни о каком heap'е речь не идет
адрес массива зафиксирован за 0x804a040
подобная ситуация и для локальных статических массивов и каких-то других вариантов

второй вариант
Bash
1
2
3
4
5
6
7
8
9
alexxx@alexxx-laptop:~/c++$ cat 2.cpp
 
int main(){   
    int Array[100];
    return Array[0];
}
alexxx@alexxx-laptop:~/c++$ g++ -g 2.cpp 
alexxx@alexxx-laptop:~/c++$ readelf -a a.out | grep Array
alexxx@alexxx-laptop:~/c++$
видим, что под массив не было зарезервировано памяти

Bash
1
2
alexxx@alexxx-laptop:~/c++$ objdump -d a.out > dump
alexxx@alexxx-laptop:~/c++$ less dump
Bash
1
2
3
4
5
6
7
8
9
10
08048494 <main>:
 8048494:       55                      push   %ebp
 8048495:       89 e5                   mov    %esp,%ebp
 8048497:       81 ec 90 01 00 00       sub    $0x190,%esp
 804849d:       8b 85 70 fe ff ff       mov    -0x190(%ebp),%eax
 80484a3:       c9                      leave  
 80484a4:       c3                      ret    
 80484a5:       90                      nop
 80484a6:       90                      nop
 80484a7:       90                      nop
тут конечно какие хитрости, но видно, что массив появляется только за счет сдвига указателя стека
3
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.11.2011, 21:25
Привет! Вот еще темы с ответами:

Дан массив А на Н элементов (Н-константа). В массиве найти пять максимальных элементов. - C++
Дан массив А на Н элементов (Н-константа). В массиве найти пять максимальных элементов. Написать программу по шагам. Добавлено через...

Двумерный массив <array>. const int value = array.size(); value не константа? - C++
#include &lt;array&gt; #include &lt;iostream&gt; using std::array; using std::cout; /*ФУНКЦИЯ ЗАПОЛНЕНИЯ МАССИВА ЗНАЧЕНИЯМИ*/ template...

Даны функциональная константа, предикатная константа и определённое количество аксиом. Как построить модель - Логика и множества
Даны функциональная константа, предикатная константа и определённое количество аксиом. Как построит модель?

Модем (роутер) не даёт авторизоваться на некоторых сайтах, а также не даёт зарегистрировать антивирус - Сетевое оборудование
Здравствуйте! У меня такая ситуация. Обратилась ко мне знакомая - компьютер заблокировался (порнобаннер). Ну, я взял её комп и первым...


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

Или воспользуйтесь поиском по форуму:
45
Yandex
Объявления
25.11.2011, 21:25
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru