Метценгерштейн 0 6 июня, 2017 Опубликовано 6 июня, 2017 · Жалоба Есть ф-я, где локально объявлен некий массив. И я возвращаю указатель на этот массив. Смущает, что он локальный и на стеке. Он вернется в вызывающую ф-ю? Ничего по пути не потеряется? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 2 6 июня, 2017 Опубликовано 6 июня, 2017 · Жалоба Есть ф-я, где локально объявлен некий массив. И я возвращаю указатель на этот массив. Смущает, что он локальный и на стеке. Он вернется в вызывающую ф-ю? Ничего по пути не потеряется? Ну судя по тому что вы профессионал, то знаете что делаете. Поэтому могу только предложить идею в начале массива оставить некоторую страховочную область которая может засоряться эпилогами и прологами при вызовах функций. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 июня, 2017 Опубликовано 6 июня, 2017 · Жалоба Когда вернулись из функции, ее локального массива уже нет, если он не статический. Возвращать указатель на ничто? Только профессионалу позволено, потому что реально массив все еще плехается где-то в ОЗУ. :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Метценгерштейн 0 6 июня, 2017 Опубликовано 6 июня, 2017 · Жалоба ну а без шуток? Получается, что массив удаляется. Разве что может повезти, и он еще не успел затереться в ОЗУ? И по- хорошему, так нельзя делать. Верно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 183 6 июня, 2017 Опубликовано 6 июня, 2017 · Жалоба Ну судя по тому что вы профессионал, то знаете что делаете. Да - профессионал в написании сообщений в форуме Человека, делающего подобное: Есть ф-я, где локально объявлен некий массив. И я возвращаю указатель на этот массив. Смущает, что он локальный и на стеке. не то что профессионалом, а и просто знающим - язык не поворачивается назвать... :smile3046: И по- хорошему, так нельзя делать. Если хотите заложить сюрпризов в ПО, чтобы насолить работодателю, уволившему Вас с работы, то можно. Чтобы вернуть некое содержимое из функции на стеке (в автоматической памяти), обычно такой массив создаётся в вызывающей функции и указатель передаётся в вызываемую. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 6 июня, 2017 Опубликовано 6 июня, 2017 · Жалоба ну а без шуток? Получается, что массив удаляется. Разве что может повезти, и он еще не успел затереться в ОЗУ? да пройдись в дизасме, и все увидишь. должно быть примерно так: перед вызовом функции StackPointer = 1000 StackPointer уменьшается на 100 и стал 900 ( 100 это сколько нужно для размещения твоего массива, прочего ( используемые регистры тоже будут сохранены в стек ) в процессе работы функции ) по выходу из функции StackPointer + 100 и равен 1000 дальнейшие команды могу похерить твой массив, а могут и не похерить - но никто специально не стирает p.s. если функция1 вызывает функцию2 а она вызывает функцию3 то компилятор, может единожды сделать StackPointer "туды/сюды", а не трижды Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Метценгерштейн 0 6 июня, 2017 Опубликовано 6 июня, 2017 · Жалоба Профессионал- тот, кто не стесняется озвучить непонятный для него момент, пытается закрыть этот вопрос. Ламер- тот, который пишет как умеет, не пытается задать неудобный вопрос, боится, что его начнут поливать. И код у него соответствующий. А кто каждый из нас- определяем сами. За ответы- спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 6 июня, 2017 Опубликовано 6 июня, 2017 · Жалоба За ответы- спасибо. такая реакция у публики, потому что это азы вот "Язык программирования Си" Брайан Керниган, Деннис Ритчи Каждая локальная переменная функции возникает только в момент обращения к этой функции и исчезает после выхода из нее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 6 июня, 2017 Опубликовано 6 июня, 2017 · Жалоба Голосую за то, что это просто толстый троллинг. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 6 июня, 2017 Опубликовано 6 июня, 2017 · Жалоба Не иначе... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
conan 0 8 июня, 2017 Опубликовано 8 июня, 2017 · Жалоба С точки зрения спецификации языка C доступ к локальным переменным функции после её завершения влечет неопределенное поведение. Если копнуть глубже, то поведение зависит от устройства конкретного компилятора и конкретной платформы. На микроконтроллерах и ОС типа DOS данные в локальном массиве после завершения функции могут быть перезаписаны обработчиками аппаратных прерываний. В ОС использующих механизм страничной адресации памяти диапазон массива теоретически вообще может оказаться unmap-ленными и тогда даже попытка чтения приведет к segmenation fault и немедленному завершению программы Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AnatolyT 0 8 июня, 2017 Опубликовано 8 июня, 2017 · Жалоба Не стоит рассчитывать на сохранность локальных переменных вне функции. Поступаю следующим образом, определяю область памяти с помощью malloc() и передаю указатель в функцию, которая в свою очередь тоже может передать и возвратить его, после возврата указателя освобождаю область с помощью free(). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 3 8 июня, 2017 Опубликовано 8 июня, 2017 (изменено) · Жалоба Не стоит рассчитывать на сохранность локальных переменных вне функции. Поступаю следующим образом, определяю область памяти с помощью malloc() и передаю указатель в функцию, которая в свою очередь тоже может передать и возвратить его, после возврата указателя освобождаю область с помощью free(). Откровенно странный способ, ваш компилятор не поддерживает С11 или C99? Изменено 8 июня, 2017 пользователем one_eight_seven Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
conan 0 9 июня, 2017 Опубликовано 9 июня, 2017 · Жалоба Откровенно странный способ, ваш компилятор не поддерживает С11 или C99? Почему странный? Стандартный способ. Два основных подхода: 1. Вызывающая сторона выделяет память и передает адрес буфера в функцию в качестве аргумента. Функция заполняет буфер результатом работы. За освобождение памяти отвечает вызывающая сторона. Иногда, когда заранее неизвестно сколько надо будет памяти, чтобы поместился результат, функция вызывается два раза. Первый раз -- с 0 в качестве указателя на буфер и тогда, функция не генерирует результат, а только вычисляет и возвращает размер необходимого буфера. Потом вызывающая сторона готовит буфер нужного размера и вызывает функцию повторно, но уже с указателем на буфер. Такой под-подход встречается, например, в WinAPI. 2. Память выделяет сама функция и возвращает указатель на этот блок, заполненный результатом работы. Не кошерно, если потом память освобождается прямым вызовом free. По-хорошему должна быть отдельная функция которая просто освобождает память: Data *doSomething(); void free(Data *); Именно так устроено большинство C-библиотек. Есть набор функций, которые выделяют память и возвращают указатель и есть отдельная функция, которая по этим указателям память освобождает. Такой подход, например, позволяет подключать библиотеки, которые собраны другим компилятором (или тем же, но с другими настройками, которые влияют на распределитель памяти) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 3 9 июня, 2017 Опубликовано 9 июня, 2017 · Жалоба Почему странный? Стандартный способ. Два основных подхода: 1. Вызывающая сторона выделяет память и передает адрес буфера в функцию в качестве аргумента. Функция заполняет буфер результатом работы. За освобождение памяти отвечает вызывающая сторона. Иногда, когда заранее неизвестно сколько надо будет памяти, чтобы поместился результат, функция вызывается два раза. Первый раз -- с 0 в качестве указателя на буфер и тогда, функция не генерирует результат, а только вычисляет и возвращает размер необходимого буфера. Потом вызывающая сторона готовит буфер нужного размера и вызывает функцию повторно, но уже с указателем на буфер. Такой под-подход встречается, например, в WinAPI. 2. Память выделяет сама функция и возвращает указатель на этот блок, заполненный результатом работы. Не кошерно, если потом память освобождается прямым вызовом free. По-хорошему должна быть отдельная функция которая просто освобождает память: Data *doSomething(); void free(Data *); Именно так устроено большинство C-библиотек. Есть набор функций, которые выделяют память и возвращают указатель и есть отдельная функция, которая по этим указателям память освобождает. Такой подход, например, позволяет подключать библиотеки, которые собраны другим компилятором (или тем же, но с другими настройками, которые влияют на распределитель памяти) Conan, этот метод стандартный для C89. Если на момент вызова функции, которая должна только заполнить буфер, размер буфера уже известен, а у вас в пункте 1 так, то с этим в C99/С11 прекрасно справляется автоматическая модель памяти, нет нужды рисковать с использованием ручного управления памятью. Я понимаю, что лучший инструмент - это не тот, который лучше, а тот, который вы знаете, и это нормально. Но советовать такое в 2017 - это ретроградство, и даже немножко вредительство, насколько мне изветсно, даже Будда терял самообладание, когда ему приходилось пользоваться malloc'ом. По пункту 2. Врапперы вокруг free и malloc полностью поддерживаю там, где без malloc и free не обойтись. Но в полседнее время мало встречаю необходимости в malloc. А вот free нужна гораздо чаще. Как по мне, malloc нужен там, где потом будет использоваться realloc, но, повторюсь, нужды в этом сейчас куда меньше, чем об этом написано в книжках 80-х и 90-х годов. P.S. Не знаком с WinApi, но Win в начале позволяет говорить о том, что это microsoft'овское, а у них компилятор не поддерживает C99/C11. По крайней мере, отказ о поддержке этих стандартов языка был официально объявлен, когда я последний раз рассматривал возможность прикоснуться к Visual Studio. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться