реклама на сайте
подробности

 
 
> Возвращение указателя на динамический массив
Nikitoc
сообщение Mar 1 2012, 15:03
Сообщение #1


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Всем привет!
Вопросик простой, но для полноты картины происходящего в компиляторе (или в МК) мне нужно этот вопрос разъяснить. Допустим, есть какая-то функция:
Код
WORD *Multiple (BYTE A, BYTE B){
           WORD *result;
           result = (WORD *)malloc(1);
           *result = A * B;
           return result;
       }


Собственно вопросы:

1. Где необходимо удалять эту переменную result (я имею в виду вызов ф-ции free())? Только в той функции, в которой она была выделена (Multiple()) или же можно сделать это в вызывающей функции по полученному указателю?
2. Я правильно понимаю, что возвращать указатель можно потому, что динамически выделенная переменная помещается в кучу, а не в стек?
3. Как называется область оперативной памяти, которая не отводится под кучу или стек? Как она используется компилятором (что туда "ложится")?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Сергей Борщ
сообщение Mar 1 2012, 19:44
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (toweroff @ Mar 1 2012, 20:28) *
то есть malloc просматривает при выделении нужную "дырку", в не зависимости, как и где вызван запрос на область памяти?
посему - free освобождает этот кусок, образуя дырку?
Существует множество реализаций менеджеров памяти со своими преимуществами и недостатками. Для понимания их работы можно рассмотреть простейший случай. Куча - отдельный зарезервированный участок памяти. При старте - она одна большая "дырка". При вызове malloc() из нее "откусываются" кусочки запрошенного размера плюс еще немного для служебной информации. При вызове free() эти кусочки становятся небольшими "дырками", а если они с какой-либо стороны соприкасаются с другой "дыркой" - то эти две дырки объединяются в одну "дырку" суммарного размера. Таким образом, если освободить все выделенные malloc() переменные - будет снова одна большая "дырка".
QUOTE (toweroff @ Mar 1 2012, 20:28) *
и без разницы где это вызывается?
Да, естественно. malloc возвращает указатель на "откушенный" участок. Грубо говоря указывать вы можете откуда угодно, пока указываете в это место.
QUOTE (toweroff @ Mar 1 2012, 20:28) *
также, выделяя/освобождая как попало куски памяти, получаем вариант, когда суммарно память свободная есть, а выделить ее не можем, потому как нет одной дырки подходящего размера?
Совершенно верно. Это называется фрагментацией кучи и является главным ее недостатком. Именно из-за нее и стараются не использовать динамические переменные в контроллерах. В основном именно для борьбы с ней и существуют различные менеджеры памяти.
QUOTE (toweroff @ Mar 1 2012, 20:28) *
валяйте
В этой функции не возвращается адрес локальной переменной. Локальная переменная тут одна - result и возвращается ее значение. А вот значение ее является указателем на какую-то точку глобальной кучи (адресом). Так что не ойой, а хихи 08.gif . Ваш ход.
QUOTE (xemul @ Mar 1 2012, 20:54) *
Мне больше по душе, когда "выделил - ... - освободил" очевидно (свернув промежуточные {} при необходимости). Мне и своего склероза памяти хватает sm.gif
А, в этом смысле... Ну тогда все объектно-ориентированное придется отменить.
QUOTE (Nikitoc @ Mar 1 2012, 20:54) *
я спросил про "неназванную" область оперативной памяти (которая не куча и не стек) потому что столкнулся с этим при работе в Keil uVision
А, понял. Глобальные переменные размещаются в первую очередь. А уже что осталось от ОЗУ после них - отдается под стек и кучу. Ну а что и они не использовали - висит без пользы и вносит вклад в глобальное потепление.
QUOTE (Nikitoc @ Mar 1 2012, 20:54) *
Получается, что расположены эти два буфера не в стеке
Переменные бывают:
- глобальные ("видны" во всем проекте, хранят значения от старта до завершения программы)
- глобальные статические ("видны" в пределах единицы компиляции, хранят значения от старта до завершения программы)
- локальные статические ("видны" от точки объявления до конца блока, хранят значения от старта до завершения программы)
- локальные автоматические("видны" от точки объявления до конца блока, хранят значения от точки объявления до конца блока).
- динамические (создаются по malloc(), new(), уничтожаются по free(), delete()).
вроде бы ничего не забыл.
Первые три хранятся в памяти в той самой области, которая резервируется под них в первую очередь. И размер этой области линкер может легко подсчитать - это суммарный размер переменных плюс (при необходимости) некоторое количество "пропусков" для выравнивания адресов переменных. Под четвертые память выделяется на стеке в процессе работы. Под пятые память выделяется в куче.
QUOTE (Nikitoc @ Mar 1 2012, 20:54) *
(слишком мал)
Если стека не хватит - вы узнаете об этом только в процессе работы программы. Ибо расчитать расход стека очень сложно, а иногда и невозможно. Поэтому компилятор/линкер его не считает. Вы резервируете N байт, линкер их размещает. Но ни компилятор, ни линкер не скажут, что этих N байт не хватает для всех ваших локальных автоматических переменных, адресов возврата, контекста прерываний и т.п. Поэтому когда вашим данным не хватит места на стеке, они начнут налезать на данные соседней области - незанятой памяти, кучи, глобальных переменных. Тогда и начнутся чудеса.

QUOTE (_Ivana @ Mar 1 2012, 21:39) *
Тогда хорошо бы что-то (либо кучу либо стек) не ограничивать и использовать на весь оставшийся объем памяти. Просто мысли дилетанта sm.gif
Да, так и делают. Чаще стек, ибо просчитать его сложно, пусть уж растет сколько может. А когда налезет на другие данные - надо будет переписывать программу, ибо памяти взять уже ну неоткуда совсем.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Nikitoc   Возвращение указателя на динамический массив   Mar 1 2012, 15:03
- - ys05   Цитата(Nikitoc @ Mar 1 2012, 18:03) 1. Гд...   Mar 1 2012, 15:59
- - toweroff   ойой возвращать из функции адрес локальной перемен...   Mar 1 2012, 16:09
|- - xemul   Цитата(toweroff @ Mar 1 2012, 20:09) ойой...   Mar 1 2012, 16:20
|- - toweroff   Цитата(xemul @ Mar 1 2012, 20:20) Возвращ...   Mar 1 2012, 16:40
- - Сергей Борщ   QUOTE (Nikitoc @ Mar 1 2012, 17:03) 1. Гд...   Mar 1 2012, 18:18
|- - toweroff   Цитата(Сергей Борщ @ Mar 1 2012, 22:18) И...   Mar 1 2012, 18:28
|- - xemul   Цитата(Сергей Борщ @ Mar 1 2012, 22:18) К...   Mar 1 2012, 18:54
|- - _Pasha   Цитата(xemul @ Mar 1 2012, 21:54) Я не пр...   Mar 2 2012, 01:34
- - Nikitoc   Всем спасибо за ответы. Вопрос Сергею: я спросил п...   Mar 1 2012, 18:54
- - _Ivana   Это стОит того, чтобы ждать! Так и я пойму да...   Mar 1 2012, 19:39
- - toweroff   Цитата(Сергей Борщ @ Mar 1 2012, 23:44) В...   Mar 1 2012, 19:51
|- - Сергей Борщ   QUOTE (toweroff @ Mar 1 2012, 21:51) полу...   Mar 1 2012, 20:10
- - Nikitoc   Сергей, спасибо Вам большое. Разжевано предельно п...   Mar 1 2012, 19:57
- - _Ivana   Со стеком имхо ничего не поможет справиться, кроме...   Mar 1 2012, 20:00
|- - toweroff   Цитата(_Ivana @ Mar 2 2012, 00:00) Со сте...   Mar 1 2012, 20:03
- - _Ivana   Как интересно-то! Лично я бы стал пользоватьс...   Mar 1 2012, 20:17
|- - XVR   Цитата(_Ivana @ Mar 2 2012, 00:17) Если ф...   Mar 2 2012, 08:40
- - toweroff   То есть "в лоб" - (как уже упомянали) - ...   Mar 1 2012, 20:24
- - _Ivana   Ладно, уговорили: free_всё_кроме_заполненного_масс...   Mar 1 2012, 20:30
|- - Сергей Борщ   QUOTE (_Ivana @ Mar 1 2012, 22:30) просто...   Mar 1 2012, 20:55
- - toweroff   Цитата(_Ivana @ Mar 2 2012, 00:30) Ладно,...   Mar 1 2012, 21:00
- - _Ivana   Это было на правах фантазии дилетанта Убирать в к...   Mar 1 2012, 21:07
- - _Ivana   XVR спасибо, очень интересно и познавательно!   Mar 2 2012, 15:00
- - Idle   Цитатаresult = (WORD *)malloc(1); вылезаешь за гра...   Mar 3 2012, 13:41


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 08:04
Рейтинг@Mail.ru


Страница сгенерированна за 0.01403 секунд с 7
ELECTRONIX ©2004-2016