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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 26, средняя оценка - 4.77
Lindemann66
 Аватар для Lindemann66
3 / 3 / 0
Регистрация: 28.04.2010
Сообщений: 162
09.08.2011, 16:05     Отличие операции с выделением памяти и без #1
Всем привет!

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

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

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


C++
1
int arr[n];

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

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

Цитата Сообщение от Lindemann66 Посмотреть сообщение
int arr[n];
- во время работы адресс начала блока памяти неизменен...
DoZZer_
11 / 11 / 1
Регистрация: 09.08.2011
Сообщений: 53
09.08.2011, 16:13     Отличие операции с выделением памяти и без #5
Разница также состоит в том, что используя динамическое распределение памяти, вы должны сами явно вписывать уничтожение (освобождение) памяти под этим динамическим объектом, иначе можно получить нечто неконтролируемо пожирающее память..
LosAngeles
Заблокирован
09.08.2011, 16:16     Отличие операции с выделением памяти и без #6
в стеке память быстрее выделится
-=ЮрА=-
Заблокирован
Автор FAQ
09.08.2011, 16:17     Отличие операции с выделением памяти и без #7
Это
Цитата Сообщение от DoZZer_ Посмотреть сообщение
вы должны сами явно вписывать уничтожение (освобождение) памяти под этим динамическим объектом, иначе можно получить нечто неконтролируемо пожирающее память..
следствие из этого
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
во время работы приложения при повторномм выделении памяти может быть выделена уже совсем другая область
Сыроежка
Заблокирован
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 ); }
Я набирал код "на коленках", поэтому в нем могут быть ошибки, но идея понятна: функция позволяет вернуть размерность массива. Для указателей она работать не будет.
-=ЮрА=-
Заблокирован
Автор 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);//это я к примеру
Сыроежка
Заблокирован
09.08.2011, 16:35     Отличие операции с выделением памяти и без #10
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Зачем так сложно если для статики чётко это работает?
C++
1
sizeof(mass)/sizeof(mass[0]);
Вы заблуждаетесь. Как раз в вашем примере все очень сложно. Вам всегда самому нужно писать такое выражение, а в моем случае достаточно записать array_size( array ). Тем более это выражение более самодокументируемо. Не забывайте, что имя массива может быть очень сложным и составным, и тогда ваше выражение можно вообще с ошибками записать.
asics
Freelance
Эксперт C++
 Аватар для asics
2838 / 1775 / 144
Регистрация: 09.09.2010
Сообщений: 3,842
09.08.2011, 16:36     Отличие операции с выделением памяти и без #11
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
а что мы передаём в функцию, ммм-масив ли?
Нет, не масив, а адрес первого елемента.
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
09.08.2011, 16:37     Отличие операции с выделением памяти и без #12
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Зачем так сложно если для статики чётко это работает?
Зато
C++
1
array_size(array);
компактнее, красивее и легче читается. А главное, это должно защитить от попытки подсунуть туда указатель вместо массива.
Сыроежка
Заблокирован
09.08.2011, 16:45     Отличие операции с выделением памяти и без #13
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Ну это ты прав, а что мы передаём в функцию, ммм-масив ли?
C++
1
void fun(int m, int * mass);//это я к примеру
Я не понял этого вашего вопроса. Как я указал, нередки случаи в С++, когда передается ссылка на массив. И я привел такой пример для вычисления размерности массива.

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

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

new char[m][n];

Здесь уже был такой вопрос на форуме.
-=ЮрА=-
Заблокирован
Автор 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 использовать....
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
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 - это параметр шаблона, который должен быть вычислен на этапе компиляции при инстанцировании шаблона и поставлен в текст функции.
Сыроежка
Заблокирован
09.08.2011, 16:54     Отличие операции с выделением памяти и без #16
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Это делается вот так
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 использовать....
У меня был конкретный вопрос про выражение

C++
1
new char[n][m];
Вы его подменили другим выражением. Это как раз и подтверждает, что с массивами выделяемыми в куче работать сложнее. Что я и хотел сказать.
asics
Freelance
Эксперт C++
 Аватар для asics
2838 / 1775 / 144
Регистрация: 09.09.2010
Сообщений: 3,842
09.08.2011, 16:55     Отличие операции с выделением памяти и без #17
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
лучше malloc с realloc использовать....
Лучше std::vector<std::vector<int>> ипользовать, если пишешь на С++, выдержка стиля все-таки.
-=ЮрА=-
Заблокирован
Автор FAQ
09.08.2011, 16:57     Отличие операции с выделением памяти и без #18
За указатель писал к тому что юзая функции мы всё равно в них указатели передаём, ну а на счёт sizeof - я предпочитаю этот дедовский способ, мне он интуитивно понятней...
На счёт передачи в sizeof динамики - вернётся 4
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
09.08.2011, 16:58     Отличие операции с выделением памяти и без #19
Цитата Сообщение от Сыроежка Посмотреть сообщение
Кстати сказать, когда выделяется память в куче для двумерного массива, многие программисты затем испытывают трудности при работе с ним, потому что не знают, как затем обращаться с этим массивом, и как определить указатель на выделенную память.

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

new char[m][n];

Здесь уже был такой вопрос на форуме.
В С++ НЕТ двумерных массивов - только одномерные. Поэтому указанная вами запись - невозможна. Однако элементом массива может быть массив. Поэтому тут все четко: сначала выделяем память под массив (указателей), потом - память под каждый элемент массива - инициализируем указатели.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.08.2011, 17:00     Отличие операции с выделением памяти и без
Еще ссылки по теме:

Проблемы с выделением памяти C++
C++ Работа со строками и выделением памяти
C++ Задача на строки с выделением памяти

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

Или воспользуйтесь поиском по форуму:
Сыроежка
Заблокирован
09.08.2011, 17:00     Отличие операции с выделением памяти и без #20
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
В С++ НЕТ двумерных массивов - только одномерные. Поэтому указанная вами запись - невозможна. Однако элементом массива может быть массив. Поэтому тут все четко: сначала выделяем память под массив (указателей), потом - память под каждый элемент массива - инициализируем указатели.
ВЫ уверены, что указанная запись невозможна? Попробуйте ее использовать, будет ли код компилироваться?

Как-то странно звучит, что в С++ нет двумерных массивов, а в С они есть. Что-то неладно в королевском царстве!
Yandex
Объявления
09.08.2011, 17:00     Отличие операции с выделением памяти и без
Ответ Создать тему
Опции темы

Текущее время: 03:24. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru