![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
ama_kid |
|
||||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
Доброго всем времени суток...
Сразу скажу, что при написании топика почитал эту и эту тему, выданные мне форумом как "похожие темы", ответы там не сильно помогли, поиском тоже пользовался - не айс... между тем вопрос по большому счету не стОит и того количества букв, которые я тут напишу, но тем не менее, постараюсь в красках и примерах на пальцах объяснить суть ментального геморроя... Итак, недавно пришлось переводить кое-какой код с Дельфи на С++ и столкнулся с интересной для себя теоретической проблемой, которая подспудно грызла меня давно, но как-то не было случая с ней основательно разобраться... Дело в том, что есть, допустим, гипотетический код на дельфи:
1) Очевидно, что если я оставлю функцию в таком виде - я гарантирую себе весёлую жизнь с утечками памяти, ибо delete\free нигде не вызываются и память по выходу из функции утекает. В итоге - закономерный вопрос: где необходимо освобождать память? Выделять память до вызова функции нет смысла, ибо размер буфера неизвестен; освобождать внутри функции - бессмысленно; выделять внутри, а освобождать после выхода - некрасиво (и есть небезосновательное подозрение, что неправильно)... 2) Как вообще правильно действовать в таких случаях? Использование разнообразных классов типа std::string не предлагать, сам знаю, что они для этого и предназначены, но так же помню, что разнообразные библиотечные функции, работающие с char * - работают вполне корректно и возвращают указатели на вполне валидные буферы. Да, я понимаю, что там используется несколько другой подход - передаются указатели на буферы, где необходимо разместить ответ, но не до конца понимаю, где происходит выделение памяти под эти буферы? (Тот же strcpy - как и где выделяет память под char *strDestination?). Единственный более-менее внятный ответ на похожий вопрос от _hunter'а я увидел у RAN, но и там возник вопрос: а что если память под параметр char* param выделена не через new, а допустим, через malloc (при условии, что я не знаю точно)? В общем, буду признателен, если помимо ответов "ха-ха, ты далпайоп!" и "кури маны, дятел!" (как любит говорить мне мой друг) будут более содержательные разъяснения ![]() -------------------- самурай без меча подобен самураю с мечом, но только без меча |
||||
|
|||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
ну если посмотреть апишные функции, то как правило им передаётся буфер и размер, а они возвращают количество записанных символов и, если что, количество символов, которые не влезли. По большому счету мне непонятны твои сомнения относительно new или malloc. Ведь полюбому буфер надо выделять перед вызовом и функции побарабану как он получен (хоть массив в стеке). Возвращать из функции имеет смысл если возвращается const char* заранее определененый, а в твоем случае нужно подготовленный буфер передавать и заполнять его. Добавлено через 5 минут и 2 секунды если смотреть твой код
неправильно это. Плохо делать выделение памяти внутри функции. Так ты делаешь вызывающий код зависимым от реализации этой функции. |
|||
|
||||
Walker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 363 Регистрация: 23.10.2006 Репутация: 1 Всего: 16 |
Хоть сам ещё нахожусь в процессе познания, принять участие в обсуждении интересно. Может вместе найдём истину.
![]() Сразу оговорюсь, я работаю исключительно с С. На первый взгляд складывается ощущение, что при грамотном проектировании такой ситуации возникать просто не должно.
Правильно понимаете. Это чревато следующей ошибкой, которая ловится, зачастую только под отладчиком. Если Вы передаёте адрес как аргумент, то работаете с локальной копией указателя, и внешний мир ничего не знает о выделенном участке. Это будет бесцельная трата памяти. Если же вы используете адрес в качестве возвращаемого значения, то аргументом передавайте размер, Ваша функция будет выполнять роль оболочки над malloc. Напишите обратную функцию - оболочку над free. Библиотечные функции и strcpy в том числе используют именно преопределённые буферы, за выделение и освобождение которых отвечаете Вы. Попробуйте представить иной пример, тогда найдём в открытых исходниках аналог и разберёмся. Пока я такого не встречал. ![]() PS Пока инет глючил, Fazil6 опередил. ![]() Это сообщение отредактировал(а) Walker - 6.6.2008, 10:54 -------------------- "От вчерашних побед остаётся усталость, если завтрашний день не сулит ничего..." |
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
как вариант сначала запрашивать размер буфера, а потом выделять буфер и вызывать GetString, но честно говоря я бы так не делал.
По любому используя С++ лучше контейнер (стандартный или самодельный) вместо char* |
|||
|
||||
Mayk |
|
||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
strcpy не выделяет память. Выделение памяти - это проблемы вызывающего strcpy кода.
курить std::string (c++) и realloc © -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||
|
|||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
вот те раз... приехали... нигде он ее не выделяет. Оба буфера выделены до вызова. |
|||
|
||||
Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
realloc курить сюда. зы! опять мои посты не склеились >ОДНАКО< Это сообщение отредактировал(а) Mayk - 6.6.2008, 10:56 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
Andrey44 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1501 Регистрация: 4.12.2006 Где: На работе Репутация: 2 Всего: 26 |
А можно ли вообще возвращать адрес локальной переменной?
Компилятор по-этому поводу предупреждает! -------------------- ????? ??, ??????? ?????. ![]() |
|||
|
||||
ama_kid |
|
||||||||||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
Ага, это если память выделена malloc... А если через new? Делать delete и new заново? Насколько это корректно с точки зрения областей видимости? А если неизвестно - через что выделена память? ![]()
-------------------- самурай без меча подобен самураю с мечом, но только без меча |
||||||||||
|
|||||||||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
можно, но не нужно Добавлено через 2 минуты и 47 секунд два варианта 1. отделить функционал от работы с памятью (выделение/освобождение) 2. использовать статический буфер (TLS-буфер в случае многопоточности) -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
Alek86 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
на плюсах это легко:
а не ООП тем и хуже, что ты сам обязан за всем следить |
|||
|
||||
ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
Да я-то и не против следить, мне собственно и нужно знать - КАК следить? Как правильно будет написать возврат строки из функции?
![]() -------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
См аллокаторы в stl. -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
mes |
|
||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
и в С и в С++ работа по выделению памяти внутри функции не этична
но в С++ можно написать оболочку над буффером (чем с данной точки зрения и является std::string) "стык" между С и С++ приводится к сишнему виду, со всеми вытекающими проблемами.. поэтому имхо вопрос должен относится к чистому С, а не к плюсам
перекосило от конструкции, хотя отработает она без проблем. |
||||
|
|||||
Alek86 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
думаю имелось в виду сделать 2 функции - получение длины данных и заполнение буфера тогда - получил длину - создал буфер - заполнил (GetString) - воспользовался данными - удалил буфер а если получение длины неотделимо от GetString, то или выделяй большой буфер и пускай функция выдает ошибку, если его оказалось недостаточно или уж выделяй внутри функции и возвращай
Добавлено @ 11:59 стандартный прием когда хочется, чтобы функция нужные данные возвращала, и хочется избежать лишних вызовов конструкторов копирования если функция внутри dll находится, то плюсы тут наравне с сями, ибо реализация auto_ptr не специализирована и даже размеры классов для борланда и мелкософтового компилеров могут отличаться Это сообщение отредактировал(а) Alek86 - 6.6.2008, 12:00 |
|||
|
||||
ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
Опять же - поднимаемся до уровня библиотеки шаблонов С++. Оно, конечно, введено в стандарт и все такое, но проблема в том, что во многих компиляторах С, применяемых, допустим, в промышленных контроллерах, она попросту отсутствует. Поэтому интересно узнать решение средствами языка, а не каких-то библиотек (даже если это и трудоёмко). Или наоборот - получить подтверждение, что это невозможно...
![]() Добавлено через 2 минуты и 32 секунды Во-во, про второй способ поподробнее пожалуйста... На что должен указывать char* p_str? -------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
Alek86 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
||||
|
||||
Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
delete [] != delete.
Ну так вместо шаблонов передавай указатели на malloc/realloc/free если так заботишся о обобщенности, делов то. -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
-------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
ДО вызова/а если требутеся - то ВО время. Это сообщение отредактировал(а) Mayk - 6.6.2008, 12:09 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
Lazin |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
можно передавать в функцию не только массив и его размер, но и указатель на функцию изменяющую размер массива...
использовать можно как с динамическим массивом
так и с массивом размещенным в стеке
|
||||||
|
|||||||
Alek86 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
точно интересно, какой хороший человек решил их разделять... внутри функции но это только в том случае, если никак не можешь отделить подсчет необходимой длины от GetString (или он просто будет долго работать) |
|||
|
||||
ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
-------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
std::copy блин На что передаются указатели в аллокаторы? На что передаются указатели в аллокаторы? На что передаются указатели в аллокаторы? На что передаются указатели в аллокаторы? На что передаются указатели в аллокаторы? На что передаются указатели в аллокаторы? На что передаются указатели в аллокаторы? Это сообщение отредактировал(а) Mayk - 6.6.2008, 12:14 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
Lazin, привел хороший пример, но к тебе тот же вопрос...
-------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
новый массив = new[] memcpy из старого в новый (если нужно) delete[] старый массив |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
тут два варианта , или "чистый" виртуальный интерфейс, либо С -подход (не смотря на то что прога на С++) |
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
в си алокаторов и new/delete нету, так к слову...
|
|||
|
||||
nirburg |
|
|||
Новичок Профиль Группа: Участник Сообщений: 10 Регистрация: 20.3.2008 Репутация: 1 Всего: 1 |
ama_kid, перед вызовом подобных функций использую предварительное выделение заведомо достаточного объема памяти в стеке, либо хипе (зависит от необходимых размеров). соответственно, память освобождается в той же функции, которая ее выделяла. если максимальный размер возвращаемых данных никак заранее нельзя определить (хотя бы примерно), то, дабы не обременять себя "ментальным геморроем", использую std::string.
т.к., судя по всему, эти пути решения вас не устраивают, можно делать "пробный" вызов функции для определения необходимого объема памяти, выделять эту память, после чего вызывать функцию "по-настоящему". такой вариант, кажется, применяется в некоторых функциях ядра Windows, или, по крайней мере, где-то недалеко от ядра ![]() поясню:
как-то так, в общем. |
|||
|
||||
ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
хмм.. ну тада уж проще использовать с
std::string ![]() Добавлено @ 12:20
Ну, на самом деле иногда приходится работать со срещенным С\С++ - new\delete есть, а библиотеки шаблонов нет ![]() Добавлено @ 12:21 В общем-то полностью согласен, и изначальный вопрос родился из мыслей: "а нельзя ли сделать как-нить эдак, чтобы не так?!" Это сообщение отредактировал(а) ama_kid - 6.6.2008, 12:27 -------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
Alek86 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
даже чистый вирт интерфейс не может работать с переменными типов std::auto_ptr и т.п. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
||||
|
||||
nirburg |
|
|||
Новичок Профиль Группа: Участник Сообщений: 10 Регистрация: 20.3.2008 Репутация: 1 Всего: 1 |
как-нибудь эдак, конечно, можно. вопрос - нужно ли? ![]() (шепотом) там народ уже интерфейсы обсуждает )) скоро, чувствую, все сведется к необходимости создания дерева классов со сложной иерархией, наследованием, и прочей модной шелухой =) |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
тем более вопрос был не об auto_ptr , а о том как избежать проблем с выделением памяти внутри функции
Добавлено через 1 минуту и 11 секунд
)) |
|||
|
||||
ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
Удалить-то мы его удалим, а куда денется выделенная по-новой память при выходе из функции?
-------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
если изменять память внутри функции надо передаватж в нее ссылку на указатель.. тогда ее можно будет удалить извне .. но в таком случае саму функцию желательно называть типа newString - чтобы было ясно что внутри происходит выделение памяти .. а так же желательно чтоб был ее антоним типа deleteString - но такой подход только в особенных случаях в остальных как и говорилось выше - нужно выделять памятж вне функции |
|||
|
||||
ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
Опять же - а если вне функции неизвестен размер требуемой памяти?
Хорошо, у меня вроде бы сформировался более-менее основной вопрос, попробую его сформулировать: как после выполнения оператора
1) размер строки становится известен только внутри GetString()... 2) пользуясь new\delete? P.S. Для случаев с malloc\realloc\free я более-менее уже понимаю... -------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
присваивать так низя, юзай strcpy
|
|||
|
||||
ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
что передавать в strcpy?
Ну это гипотетический пример, хоть strcpy, хоть что-то другое , без разницы, главное - на выходе получить валидный буфер Это сообщение отредактировал(а) ama_kid - 6.6.2008, 13:08 -------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
Fazil6 |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
Добавлено через 1 минуту и 8 секунд кстати
|
||||||
|
|||||||
ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
Fazil6, ага, вариант понятен... В принципе, я так и делал всегда...
Кстати, щас только сообразил, что непроходимо туплю - сам же на свой вопрос вывесил в топике ответ - ссылка ответа от RAN. В связи с этим вопрос - насколько корректен приведённый там пример? Просто никто там после этого не отписался по поводу правильности\неправильности. Если он правилен - тогда вопрос снимается... -------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
JackYF |
|
||||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Ого, сколько написали...
Подытожу по себе (то есть, как бы это делал я). Варианта 2: 1) целевой язык - С
2) целевой язык - С++
В первом случае ты сам заботишься о том, чтобы освободить выделенную внутри функции память, во втором случае за тебя всё уже сделано. Это сообщение отредактировал(а) JackYF - 6.6.2008, 13:26 |
||||
|
|||||
ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
-------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
nirburg |
|
|||
Новичок Профиль Группа: Участник Сообщений: 10 Регистрация: 20.3.2008 Репутация: 1 Всего: 1 |
JackYF, в C нет new и delete
![]() |
|||
|
||||
mes |
|
||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
![]() ![]()
как я понял имеется ввиду этот ответ: http://forum.vingrad.ru/index.php?showtopi...st&p=109698
Это сообщение отредактировал(а) mes - 6.6.2008, 13:33 |
||||
|
|||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
Зная этого чела лично, могу сказать с определенностью, что сейчас он так делать не стал бы. ![]() Я тоже так делать не сталбы.
|
||||
|
|||||
nirburg |
|
|||
Новичок Профиль Группа: Участник Сообщений: 10 Регистрация: 20.3.2008 Репутация: 1 Всего: 1 |
||||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
ничем не обзавелся .. просто значения указателя не возврашается из функции - т.е указатель переданный в функцию, после ее завершения, продолжает показывать на ту же самую область что и раньше (которая к тому же была удалена внутри функции) чтоб избежать этого надо либо передавать указатель на указатель, либо указатель по ссылке в коментариях в предыдушем посту это и указано )) Это сообщение отредактировал(а) mes - 6.6.2008, 13:48 |
|||
|
||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
Не, ну выделить память внутри функции и выдать её наружу вполне себе юзкейс. Так, допустим, malloc поступает ![]() |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
нет проблемы в том, чтоб выделить память внутри функции проблема в том чтоб знать когда она выделилась и удалить ее когда нужно. и самое главное, чтоб этот процесс не отвлекал от основной цели - программирование, ибо если постояно помнить реализацию каждой функции, то и с ума сойти можно ![]() |
|||
|
||||
nirburg |
|
|||
Новичок Профиль Группа: Участник Сообщений: 10 Регистрация: 20.3.2008 Репутация: 1 Всего: 1 |
mes, прошу прощения, неправильно понял
![]() Daevaorn, ну malloc'y на роду написано память внутри себя выделять. а если так будет поступать каждая гордая функция, то что с программой будет твориться, я не представляю |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
malloc и new тем и хороши что всегда не задумываясь (о том как реализована функция) понятно, что делает функция и одназначно напрашивается вывод о применение ее антонима.
однако, что нужно делать после функции GetString (..) (удалять память или нет) имхо отнюдь не очевидно ![]() поэтому (на мой взгляд) и принято "неписанное " соглашении о использовании внутри функции зараннее выделенного буффера.. Это сообщение отредактировал(а) mes - 6.6.2008, 14:12 |
|||
|
||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
а если строка больше чем буфер? Тогда ещё одну функцию заводить, которая вернет размер, потом выделить память, и только потом передать в функцию - много букв ![]() Хотя, конечно, это оптимально с точки зрения прозрачности кода. |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
![]() ![]()
|
|||
|
||||
mes |
|
||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вот пример без добавления второй функции
|
||||
|
|||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
||||
|
||||
ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 2 Всего: 95 |
В общем, как я понял, сделать средствами new\delete (без привлечения библиотек-контейнеров и выкрутасов с несколькими функциями\вызовами) аналогичный дельфёвому фокус не удастся. Что ж, будет еще один плюс в пользу malloc\realloc
![]() ![]() Хотя, если появятся новые идеи - буду рад увидеть, да и для потомков, думаю, будет полезно... ![]() -------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |