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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 26, средняя оценка - 4.77
Lindemann66
4 / 4 / 0
Регистрация: 28.04.2010
Сообщений: 162
#1

Отличие операции с выделением памяти и без - C++

09.08.2011, 16:05. Просмотров 3277. Ответов 60
Метки нет (Все метки)

Всем привет!

Не сочтите за глупость, но возник интересный вопрос, над которым давно думаю, а овтета нигде не находил

Вот нужно, допустим, создать массив из n элементов

Сделать это можно 2-мя способами


C++
1
int arr[n];

и
C++
1
int *arr = new int[n];
Но в одном случае создание массива сопровождается выделением памяти, а в другом - без
В чём принципиальная разница?
Я понимаю, в Qt сразу написано - объекты QObject необходимо создавать с выделением памяти, чтобы не было проблем
Понятно, так и делаем. А тут как правильней?
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.08.2011, 16:05
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Отличие операции с выделением памяти и без (C++):

ошибка с выделением памяти - C++
выдает ошибку в выделении памяти. никто не подскажет почему? если что -задача звучит так примерно вводим веественные числа пока не...

Конструктор с выделением памяти - C++
Среди всех данных есть указатель, память для которого выделяется в конструкторе, необходимый размер передается в параметрах конструктора....

Проблема с выделением памяти - C++
Всем привет! Нужна помощь. Создаю класс и при компиляции возникает ошибка. Не пойму причину. Помогите пожалуйста. Конструктор должен...

Проблемы с выделением памяти - C++
Здравствуйте. Есть контейнер QList <Node *> В Node свой QList <Node *>. Строю программное дерево разбора выражение. На небольших...

Работа со строками и выделением памяти - C++
Задание написать класс строк (что-то типа String). #define MAX 100 class ascii { private: char* str; int len; ...

Задача на строки с выделением памяти - C++
Добрый вечер, помогите с задачкой Выводит на экран только строки, состоящие из заданного количества слов. Возвращает количество прочих...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
oxotnik
1590 / 1067 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
09.08.2011, 16:08 #2
память выделяется всегда, только в одном случае на стеке, в другом в куче
небольшие объекты лучше на стеке, большие массивы в куче
1
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
09.08.2011, 16:08 #3
если N неизвестно на момент компиляции, то через оператор new выделяем память в куче, если известно - то можно просто в стеке int arr[n];
1
-=ЮрА=-
Заблокирован
Автор FAQ
09.08.2011, 16:10 #4
Цитата Сообщение от Lindemann66 Посмотреть сообщение
int *arr = new int[n];
- память выделяется динамически в любой свободной части оперативки, причём во время работы приложения при повторномм выделении памяти может быть выделена уже совсем другая область

Цитата Сообщение от Lindemann66 Посмотреть сообщение
int arr[n];
- во время работы адресс начала блока памяти неизменен...
2
DoZZer_
11 / 11 / 1
Регистрация: 09.08.2011
Сообщений: 53
09.08.2011, 16:13 #5
Разница также состоит в том, что используя динамическое распределение памяти, вы должны сами явно вписывать уничтожение (освобождение) памяти под этим динамическим объектом, иначе можно получить нечто неконтролируемо пожирающее память..
0
LosAngeles
Заблокирован
09.08.2011, 16:16 #6
в стеке память быстрее выделится
0
-=ЮрА=-
Заблокирован
Автор FAQ
09.08.2011, 16:17 #7
Это
Цитата Сообщение от DoZZer_ Посмотреть сообщение
вы должны сами явно вписывать уничтожение (освобождение) памяти под этим динамическим объектом, иначе можно получить нечто неконтролируемо пожирающее память..
следствие из этого
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
во время работы приложения при повторномм выделении памяти может быть выделена уже совсем другая область
0
Сыроежка
Заблокирован
09.08.2011, 16:25 #8
Цитата Сообщение от Lindemann66 Посмотреть сообщение
Всем привет!

Не сочтите за глупость, но возник интересный вопрос, над которым давно думаю, а овтета нигде не находил

Вот нужно, допустим, создать массив из n элементов

Сделать это можно 2-мя способами


C++
1
int arr[n];

и
C++
1
int *arr = new int[n];
Но в одном случае создание массива сопровождается выделением памяти, а в другом - без
В чём принципиальная разница?
Я понимаю, в Qt сразу написано - объекты QObject необходимо создавать с выделением памяти, чтобы не было проблем
Понятно, так и делаем. А тут как правильней?
Любое определение объекта сопровождается выделением памяти! Вопрос только в том, где и как выделяется память.
В первом случае у вас выделяется память в стеке, во втором случае у вас память выделяется в кучи.

Но главное, о чем здесь не упомянули, эти два опреде6ления объявляют два разных типа данных! В первом случае вы действительно определяете массив, а во-втором случае вы определяете указатель. В С++ особенно существенна разница между указателями и массивами, так как sizeof массива отличается от sizeof указателя. И кроме того в С++ могут быть определены функции, аргументами которых являются ссылки на массив. То есть в С++ можно в функции в качестве параметра передавать массивы.

Посмотрите пример шаблонной функции

C++
1
2
3
template <typename T, size_t N>
 
inline size_t array_size( const T ( & )[ N ] ) { return ( N ); }
Я набирал код "на коленках", поэтому в нем могут быть ошибки, но идея понятна: функция позволяет вернуть размерность массива. Для указателей она работать не будет.
2
-=ЮрА=-
Заблокирован
Автор FAQ
09.08.2011, 16:33 #9
Цитата Сообщение от Сыроежка Посмотреть сообщение
template <typename T, size_t N>
inline size_t array_size( const T ( & )[ N ] ) { return ( N ); }
Зачем так сложно если для статики чётко это работает?
C++
1
sizeof(mass)/sizeof(mass[0]);
Добавлено через 2 минуты
Цитата Сообщение от Сыроежка Посмотреть сообщение
В первом случае вы действительно определяете массив, а во-втором случае вы определяете указатель.
Ну это ты прав, а что мы передаём в функцию, ммм-масив ли?
C++
1
void fun(int m, int * mass);//это я к примеру
0
Сыроежка
Заблокирован
09.08.2011, 16:35 #10
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Зачем так сложно если для статики чётко это работает?
C++
1
sizeof(mass)/sizeof(mass[0]);
Вы заблуждаетесь. Как раз в вашем примере все очень сложно. Вам всегда самому нужно писать такое выражение, а в моем случае достаточно записать array_size( array ). Тем более это выражение более самодокументируемо. Не забывайте, что имя массива может быть очень сложным и составным, и тогда ваше выражение можно вообще с ошибками записать.
0
asics
Freelance
Эксперт С++
2847 / 1784 / 144
Регистрация: 09.09.2010
Сообщений: 3,841
09.08.2011, 16:36 #11
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
а что мы передаём в функцию, ммм-масив ли?
Нет, не масив, а адрес первого елемента.
1
grizlik78
Эксперт С++
1911 / 1443 / 112
Регистрация: 29.05.2011
Сообщений: 3,000
09.08.2011, 16:37 #12
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Зачем так сложно если для статики чётко это работает?
Зато
C++
1
array_size(array);
компактнее, красивее и легче читается. А главное, это должно защитить от попытки подсунуть туда указатель вместо массива.
0
Сыроежка
Заблокирован
09.08.2011, 16:45 #13
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Ну это ты прав, а что мы передаём в функцию, ммм-масив ли?
C++
1
void fun(int m, int * mass);//это я к примеру
Я не понял этого вашего вопроса. Как я указал, нередки случаи в С++, когда передается ссылка на массив. И я привел такой пример для вычисления размерности массива.

Добавлено через 7 минут
Кстати сказать, когда выделяется память в куче для двумерного массива, многие программисты затем испытывают трудности при работе с ним, потому что не знают, как затем обращаться с этим массивом, и как определить указатель на выделенную память.

Например, как правильно задать указатель для выделения памяти выражением вида

new char[m][n];

Здесь уже был такой вопрос на форуме.
1
-=ЮрА=-
Заблокирован
Автор FAQ
09.08.2011, 16:51 #14
Цитата Сообщение от Сыроежка Посмотреть сообщение
Например, как правильно задать указатель для выделения памяти выражением вида
new char[m][n];
Это делается вот так
C++
1
2
3
char ** pArray = new char *[m];
for(int i = 0; i < m; i++)
pArray[i] = new char[n];
А как быть если в программе нужно изменить длинну какой-либо одной строки
C++
1
pArray[i]
лучше malloc с realloc использовать....
0
ValeryLaptev
Эксперт С++
1041 / 820 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
09.08.2011, 16:54 #15
Цитата Сообщение от Сыроежка Посмотреть сообщение
Любое определение объекта сопровождается выделением памяти! Вопрос только в том, где и как выделяется память.
В первом случае у вас выделяется память в стеке, во втором случае у вас память выделяется в кучи.

Но главное, о чем здесь не упомянули, эти два опреде6ления объявляют два разных типа данных! В первом случае вы действительно определяете массив, а во-втором случае вы определяете указатель. В С++ особенно существенна разница между указателями и массивами, так как sizeof массива отличается от sizeof указателя. И кроме того в С++ могут быть определены функции, аргументами которых являются ссылки на массив. То есть в С++ можно в функции в качестве параметра передавать массивы.

Посмотрите пример шаблонной функции

C++
1
2
template <typename T, size_t N>
inline size_t array_size( const T ( & )[ N ] ) { return ( N ); }
Я набирал код "на коленках", поэтому в нем могут быть ошибки, но идея понятна: функция позволяет вернуть размерность массива. Для указателей она работать не будет.
Уточню.
1. Массив можно определить не только как локальный, но и как глобальный. Только для локального массива память выделяется в стеке во время работы программы. Для глобального массива память распределяет компилятор и эта память в стандарте называется static storage. Там же размещаются и статические переменные, даже локальные. Нестатические локальные переменные размещаются в автоматической памяти (automation - если не наврал - storage). Стандарт не говорит, что должен быть именно стек. Просто издревле локальные переменные размещались в стеке ВО ВРЕМЯ ВЫПОНЕНИЯ программы. Размещение в стеке массива сразу ограничивает его размер до размера стека, выделяемого по умолчанию операционной системой для программы. Размер можно увеличить, но это надо уже устанавливать режимы линкера.
Размер массива должен быть константным выражением.

2. Во втором случае, как сказал Сыроежка, мы имеем указатель, который проинициализирован адресом первого элемента массива. Причем это делается тоже ВО ВРЕМЯ ВЫПОЛНЕНИЯ программы. Отличие от первого случая - это vds делаем сами, ручками, явными операциями. В первом случае массив автоматом уничтожается, а во втором случае мы должны его убить явно сами операцией delete[]. Размер массива может вычисляться во время работы программы. Подобный массив размещается в динамической памяти (это третий вид памяти для объектов в С++ - dynamic storage). Опять же, как реализовать эту память стандарт не оговаривает.

3. Шаблонная функция, которую написал Сыроежка - это к памяти вообще отношения не имеет. N - это параметр шаблона, который должен быть вычислен на этапе компиляции при инстанцировании шаблона и поставлен в текст функции.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.08.2011, 16:54
Привет! Вот еще темы с ответами:

Строки с выделением динамической памяти - C++
Привет всем! Помогите решить вот такую задачу: Ввести две строки. Определить совпадение их слов (Первое слово 1 строки сравнить с первым...

Динамическое выделением памяти для массивов - C++
Даны три массива вещественных чисел X(25), B(30), Y(25). Из исходных массивов сформировать массив К, элементы которого равны количеству...

Обращение к структуре в классе с выделением памяти - C++
Добрый день уважаемые форумчане. Столкнулся с такой проблемой. Есть класс: class Components { struct comps{ // -- База компонентов ...

Двумерный массив с динамическим выделением памяти - C++
Помогите пожалуйста вставить вот в эту вот задачу динамическое выделение памяти: #include &lt;iostream&gt; using namespace std; ...


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

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

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