Easyelectronics.ru

Электроника для всех
Текущее время: 16 фев 2019, 00:52

Часовой пояс: UTC + 5 часов




Начать новую тему Ответить на тему  [ Сообщений: 32 ]  На страницу Пред.  1, 2
Автор Сообщение
 Заголовок сообщения: Re: Зачем в Си нужно динамическое выделение памяти?
СообщениеДобавлено: 27 июл 2017, 12:56 
Старожил

Зарегистрирован: 22 июн 2010, 21:53
Сообщения: 1003
Откуда: Brussels
aamonster писал(а):
Кстати, пример //Mt хорош. Пакеты разного размера, приходят себе потихоньку, потом уходят. Добавим сюда уход пакетов не в том порядке, в котором пришли (ну там, QoS, или порт для каких-то пакетов занят, или ещё что) - и получаем задачку, в которой динамическое выделение практически неизбежно.
Правда, именно для этой задачки я бы использовал не malloc, а свой велосипед специально разработанный аллокатор.

Так и делают - есть N пулов буферов фиксированного размера - там и аллоцируют подходящий.


Show пример


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Зачем в Си нужно динамическое выделение памяти?
СообщениеДобавлено: 27 июл 2017, 15:20 
Старожил
Аватара пользователя

Зарегистрирован: 01 ноя 2011, 23:51
Сообщения: 741
Арсений писал(а):
...но можно вызвать функцию, в которой объявляется статический массив. И после выхода из нее массив пхххх... растворится.





Кстати это не всегда возможно если массив большой..


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Зачем в Си нужно динамическое выделение памяти?
СообщениеДобавлено: 27 июл 2017, 16:14 
Старожил

Зарегистрирован: 06 фев 2011, 15:16
Сообщения: 617
Откуда: Челябинск
Арсений писал(а):
...но можно вызвать функцию, в которой объявляется статический массив. И после выхода из нее массив пхххх... растворится.
Это как???!!!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Зачем в Си нужно динамическое выделение памяти?
СообщениеДобавлено: 27 июл 2017, 16:17 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2551
Откуда: Санкт-Петербург
Это товарищ не знает разницы между автоматическими и статическими переменными. Явно говорит об автоматических.

А что буфер может понадобиться после выхода из функции - ему в голову не пришло. Ничего страшного, со временем разберётся.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Зачем в Си нужно динамическое выделение памяти?
СообщениеДобавлено: 27 июл 2017, 16:46 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2816
Эхехех.... Да этот "товарищь" со своим категоричным первым постом темы, претендующем по меньшей мере на "How to..." вообще чето заблудился в трех березах. Всё смешал - и файлы подкачки, которых в MCU не существует в том виде, которые он представляет, и флеш, и массивы. А про указатели он вообще видимо не слыхивал. Да и с представлением об организации памяти вообще - тож проблема. Зато суждения категоричные.. ну...

Статический массив, по определению языка Си, никуда не растворится при выходе из функции, потому что он объявлен квалификатором static и размещается в секции ОЗУ, определенной для таких массивов. В отличие от массивов, время жизни которых ограничено рамками функции.

Посмотрите наглядно: первая функция, в которой объявлены: обычным образом массив из 8 однобайтных элементов (автоматические), массив из 8 элементов static, и указатель, полученный динамически через malloc на 16 элементов
Код:
void Funct1(void)
{
   uint8_t array_funct[8];
   static uint8_t array_static_q[8];
   uint8_t *array_malloc;
   array_malloc = malloc(16);
        Funct2();
}

и думайте, думайте. Конец адресов RAM, равно как и вершина стека, в данном примере - 0x1FFF (старшие байты адреса опущены).
Видны наши 8 автоматических элементов в стеке и указатель, полученный от malloc.
Изображение

потом вызывается вторая функция из первой: и аналогично то же самое с индексом 2.
Код:
void Funct2(void)
{
   uint8_t array2_funct[8];
   static uint8_t array2_static_q[8];
   uint8_t *array2_malloc;
   array2_malloc = malloc(16);
}

Видно, что теперь наш массив разместился чуть дальше по адресам к началу.

Изображение

А где же наши элементы, полученные по malloc??? и где массивы static??? Смотрим, на какие адреса указывают указатели в области стеков. Видим, что они указывают уже где-то в начале адресов RAM (начинаются с 0х2000 0000) и бежим туда: вот они! первый и второй массив:
и там с удивлением (!) обнаруживаем наши static-массивы, которые мы выделяли в функциях:

Изображение

Так же, на последнем скрине, анализируя занимаемые адреса malloc-выделений, обнаруживаем "дырку" в 8 байт. Догадайтесь, что это за байда, и почему она всегда появляется между malloc-выделениями? Домашнее задание топикстартеру, разобраться, раз уж он претендует на "How to..."


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Зачем в Си нужно динамическое выделение памяти?
СообщениеДобавлено: 27 июл 2017, 17:42 
Заглядывает иногда

Зарегистрирован: 17 мар 2015, 16:18
Сообщения: 86
aamonster писал(а):
А что буфер может понадобиться после выхода из функции - ему в голову не пришло. Ничего страшного, со временем разберётся.
Вы - занятный :)

- Автоматический буфер легко удаляется из стека по завершении функции.
- Автоматический буфер нельзя передать, а вот динамический...
- Хорошо. Статический (или глобальный) буфер доступен любой функции.
- Глобальный буфер нельзя удалить, а вот динамический...
- Автоматический можно удалить
- А вот динамический...
- Статический будет доступен
- А вот динамический...
- Не хватает памяти - возьмите MCU подороже.
- Растратчик! Лучше сделаю динамические буферы.
- А если они одновременно разрастуться до размеров физ.памяти?
- Далась вам эта память! Куплю MCU подороже!
- Может лучше - статический массив и MCU подороже?
- Растратчик! Только malloc, только хардкор!
- А если физ.памяти не хватит?
- Куплю подороже, какие проблемы?

Судя по топику:
1. Динамический буфер в единственном числе легко заменяется статическим буфером такого же размера.
2. Динамический буфер в количестве "два и более" - отличный способ снизить цену аппаратной части системы за счет снижения надежности софтовой части.

Об этом следует помнить!


Последний раз редактировалось Арсений 27 июл 2017, 19:08, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Зачем в Си нужно динамическое выделение памяти?
СообщениеДобавлено: 27 июл 2017, 17:51 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2816
Апять-двацатьпять. В Си нет понятия "динамического буфера". Буфер, выделяемый с помощью аллокатора - это всего лишь У-К-А-З-А-Т-Е-Л-Ь, указатель, 4-хбайтовая переменная (в 32-битной системе), содержащая АДРЕС первого элемента выделенного буфера (массива). А указатель можно и ручками выделить, в любом месте. И даже void*. По соглашениям, размер void* = 1 байт.

Черт, ему уже и "веселые картинки" нарисовал для прозрения, а он всё еще с менторством "следует помнить". Фееричный чел, хаха :) Арсений, оставьте этот ваш менторский тон, а то недайбог кто прочтет, либо так же заблудится, либо смеяться будет.

Арсений писал(а):
- Хорошо. Статический (или глобальный) буфер доступен любой функции.

так статический с квалификатором static или глобальный?
С квалификатором static - НЕ доступен любым функциям кроме родительской. Но когда она будет вызвана, буфер заново не будет создаваться, и в нем содержимое осталось от предыдущего вызова функции, в целости и сохранности.

Арсений писал(а):
- Глобальный буфер нельзя удалить,

МОЖНО! объявите указатель на этот буфер void *ptr = globbuf и испортите его содержимое к чертям *(char*)ptr = 0x00. Теперь объявите новый буфер как указатель uint16_t *buf2 = ptr и пользуйтесь им вместо старого буфера. Даже пойдем дальше! нарежем еще буферов:
uint8_t *buf3 = ptr + 32;
int32_t *buf4 = ptr + 50;
Нннна-тебе, пользуйтесь вместо бывшего uint32_t globbuf[1000]. Но помните, обращение globbuf[10] = 50 испортит ваши новые буфера. Потому что имя буфера в системе осталось.

Арсений писал(а):
- Автоматический можно удалить

...нельзя. Он сам перестает быть актуальным, когда указатель вершины стека возвращается назад.
Арсений писал(а):
- А вот динамический...

нет такого понятия в Си.
Арсений писал(а):
- Статический будет доступен

только одной функции-родителю.

Арсений писал(а):
2. Динамический буфер в количестве "два и более" - отличный способ снизить цену аппаратно части системы за счет снижения надежности софтовой части.

- В КОРНЕ НЕ ВЕРНОЕ утверждение, потому что утверждение в значительной мере бессмысленно и поверхтностно.

Арсений, вы уж определитесь, в чем вы "варитесь" - в эмбедде или в писюках?
Потому что в эмбедде никто не будет выбирать МК впритык тютелька-в-тютельку. В большинстве случаев. Потому что:
а) прошивки могут обновляться в рамках сопровождения и поддержки устройства, добавляя или улучшая функционал. Нехватило памяти? перепаивать никто не станет.
б) прошивки могут исправляться на местах, когда обнаружен косяк не по вине программиста, а из-за недоработки составителей техзадания, а то и просто слегка другие условия, такое бывает. Программист ругается матом, но делает, потому что "косяки заказчиков - за их счет".
в) программист сам может накосячить, типа "ах чорт, сигнал на входе АЦП шумит же сильно, надо было вместо скользящего среднего фильтр Калмана ставить"
г) железо подбирается не только по объемам ОЗУ, но и по аппаратному функционалу, по доступности, по наличию вообще таких моделей.
д) двухкратная разница в объеме ОЗУ = 10-15% разницы в цене при прочих равных условиях
е) глубина "просадки" стека вниз по адресам при использовании сторонних библиотек заранее неизвестна и не поддается точному до байта описанию. Следствие - всегда, запомните, ВСЕГДА есть довольно большой запас ОЗУ, рассчитанный на потребление стека и не используемый постоянно. На тяжелых сторонних либах глубина просадки стека может быть очень и очень значительной.
ж) куча (heap), из которой распределяется память для этих ваших динамических буферов, не может быть равна размеру ОЗУ целиком. Иначе у вас всё перехлестнется.
Именно по этим соображениям, использования ОЗУ на 99%, как вы хотите - не бывает по определению.
99% - это один миг до сбоя и ->
Арсений писал(а):
Об этом следует помнить!

---------------------------------------------------------------------
PS. График использования ОЗУ МК в обобщенных среднестатистических применениях:


Вложения:
Без-имени-1.png
Без-имени-1.png [ 70.11 Кб | Просмотров: 588 ]
Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 32 ]  На страницу Пред.  1, 2

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB