| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Инициализация указателей, переданных в параметрах |
| Автор: INHazeR 21.5.2007, 00:45 | ||||
имеется некая функция
Необходимо, чтобы после выполнения данной функции по адресу s находилась некая строка (массив char), а по адресу p - массив целых чисел. В случае с целыми числами сделал просто
т.к. было известно, что возвращаемый массив всегда из 3-х чисел. При этом, приходится создавать этот массив вне функции, до ее вызова. В случае с массивом чаров, даже при предварительном создании массивов соответствующей длины, вызов внутри Foo функций itoa ведет к ошибкам... вроде бы как память не выделена. В общем, как по этим указателям корректно создать и заполнить соотвествующие массивы? Заранее спасибо. |
| Автор: INHazeR 21.5.2007, 00:54 |
| Пробовал выделять больше памяти, эффект тот же.. Интересует общая технология выделения памяти и инициализация таких массивов в данном случае... |
| Автор: zkv 21.5.2007, 00:58 | ||||||
а это делали:
ммм.. Какая такая общая технология? Это что ли:
? |
| Автор: Xenon 21.5.2007, 01:59 | ||
zkv, ?
Или это ирония была? |
| Автор: zkv 21.5.2007, 02:17 |
вроде не иронизировал, человек спросил про общую технологию выделения памяти, ну я ответил вообщем или ты про оператор delete[]? Да, ошибочка вышла |
| Автор: jonie 21.5.2007, 10:22 | ||
в общем могу, конечно, и ошибаться.... |
| Автор: Anikmar 21.5.2007, 10:27 | ||
Нет, вы не ошибаетесь. Но лучше все равно вызывать delete[]. Чтобы была железная привычка. Это полезно, если при написании программы захочется использовать не простой тип, а собственный. И можно забыть, что освободждалась память "по-простому", появится утечка. |
| Автор: Daevaorn 21.5.2007, 10:29 | ||
new/delete и new[]/delete[] - все другие комбинации UB и ошибка всегда. |
| Автор: Anikmar 21.5.2007, 10:42 | ||||
Если брать Билдер с запущенным CodeGuardom, то на простых типах
Ошибки утечки не возникает, только предупреждение. А если использовать свой тип - то возникает утечка. Тем не менее так делать не надо, разные компиляторы возможно ведут себя по-разному. Хотя я не помню что написано в стандарте по этому поводу, но точно помню, что в литературе по простым типам иногда делалась поблажка - может быть поэтому такое мнение и витает, что на простых типах ошибки нет. |
| Автор: Xenon 21.5.2007, 12:13 |
| Начинается ... Где-то мы уже об этом спорили с Earnest Даже тему нашел http://forum.vingrad.ru/forum/topic-144984/15.html |
| Автор: INHazeR 21.5.2007, 12:23 | ||
| Гм. Все-таки непонятно, как по данному адресу (переданному в параметре функции) выделить память и заполнить ее значениями. Варианты типа void Foo(char* s, int* p)
не годятся, насколько я понимаю, так как адрес (s) сам по себе неизменен, этот указатель создали где-то вне функции и передали сюда, так что присваивать ему новое значение внутри функции бессмысленно, разве не так? При выходе из функции он снова примет прежнее значение, а выделенная нами память останется мертвым грузом где-то в куче. По-моему, необходимо выделить память по заданному адресу, а не найти память и присвоить адрес начального байта этой памяти в указатель... или я ошибаюсь? |
| Автор: Daevaorn 21.5.2007, 12:26 | ||
INHazeR,
|
| Автор: Anikmar 21.5.2007, 12:28 | ||
Ничего не начинается, вы что думаете, что я буду отстаивать такую точку зрения? Я просто говорю про конкретное поведение того же Билдера, думаю, в остальных компиляторах будет также - блок удалится, но так делать НЕ НАДО. Можно, конечно, асмовский код посмотреть. Но думаю, что с точки зрения менеджера памяти - ему все равно, что в этом блоке памяти находится, он его будет идентифицировать по адресу, поэтому удалить должен. Но это - все равно пурга, если выделили память new[] то удалять надо delete[] без всяких там предположений. Так что, Xenon, вы полностью правы и спорить я даже не собирался - но в литературе, действительно, встречается такая ерундень - типа для базовых типов большого значения не имеет delete использовать или delete[]. К сожалению моего английского не хватает точно перевести соответствующую главу стандарта, но мне кажется что именно UB там не значится (но спорить не буду - не уверен). |
| Автор: Xenon 21.5.2007, 12:42 |
| Anikmar, ну просто предпосылки к спору с Daevaorn были, поэтому я уже воскинул руки к небу, а то уже которая тема религиозных войн ... наболело просто А которая глава стандарта? Я просто в стандарте не смотрел. |
| Автор: Anikmar 21.5.2007, 12:52 | ||
5.4.1 и 5.4.2. Кстати, вот еще доказательство, что менеджеру памяти по барабану, что находится в блоке - такой код работает без проблем и CodeGuard молчит как рыба об лед:
|
| Автор: archimed7592 21.5.2007, 13:52 |
| фраза аналогична следующей: если взять компьютер васи пупкина, находящийся в зимбабве, то утечки не будет... ну да, может и не будет... только вот зачем делать такие высказывания не совсем понятно Добавлено через 8 минут и 26 секунд 5.3.5 |
| Автор: Anikmar 21.5.2007, 14:15 | ||||
Почему не понятно? jonie высказал мнение, с котороым в общем то я согласен, и спор Xenon-а и Earnest я посмотрел - на самом деле однозначного мнения не возникло. Я посмотрел стандарт, но моего английского не хватило - вот я и решил подождать, когда Xenon посмотрит стандарт (я так понимаю он сильнее меня в английском) и скажет однозначное мнение. А по поводу Билдера и т.п. - я просто не смотрел другие компиляторы, а это мнение лично видел по-моему у того же Архангельского: если массив выделяется под простые типы, то оператор delete освободит блок и утечки не будет. Если CodeGuard отключить - то все работает нормально, блок освобождается, ругани не происходит. Если включить, то на простых типах CodeGuard выдает предупреждение на несоответствии способа выделения и освобождения памяти, а вот на собственных - ругается капитально и кричит об утечке. На самом деле, я считаю что такое высказывание нужно было сделать - так как мнение о том, что для стандартных типов не обязательно использовать [] достаточно распространенное, я у многих его встречал и сам лично читал в литературе. Но мнения это мнения, а вот что говорит по этому поводу стандарт было бы интересно узнать. Лично я всегда использую одну и ту же форму выделения памяти чего и другим настоятельно рекомендую. Но вариант UB в этом случае тоже как-то плоховато смотрится - это все-таки вещь достаточно ответственная. И от оператора delete ожидается все-таки освобождение памяти. Если менеджер памяти четко знает как выделен блок, то почему тогда не выкинуть исключение? Наверное менеджера ничего кроме указателя на блок не интересует, тогда UB просто нелогичен... В общем пошел флуд, размышления о вечном
Сравнение неадекватное. Билдер является нормальным компилятором, со своими тараканами, но тут на вкус и на цвет... мне кажется компиляторов без недостатков не бывает. Я вообще и не собирался спорить - это был не спор, а попытка выяснить все-таки: как стандарт предписывает вести себя оператору delete. Конкретно Билдер ведет себя так. Если в стандарте написано UB - значит Билдер придерживается стандарта. Если написано, что должен освобождать блок - значит тоже придерживается. |
| Автор: archimed7592 21.5.2007, 14:32 | ||||
может больше не будем даже упоминать даже о возможности такого в билдере с тараканами? Добавлено через 4 минуты и 15 секунд эээ... хотя тут сказано, что нельзя делать new->delete[] по поводу new[]->delete чуть выше:
|
| Автор: Anikmar 21.5.2007, 14:44 | ||
Я вообще-то ни слова не говорил про второй вариант нотации. Т.е., что можно использовать delete[] к объекту выделенному просто new. Это и ежу понятно - какие деструкторы он вызовет? С этим то как раз все ясно. Я говорил, что интересно бы узнать, как должен по-стандарту вести себя delete, примененный к объекту, выделенному new[] По поводу тараканов: Вариант UB предусматривает любое поведение - так что Билдер по-любому ведет себя соответствующим стандарту образом. И почему собственно мы должны не упоминать о специфике поведения конкретного транслятора? Сейчас возникло обсуждение реализации конкретного участка стандарта, я пользуюсь билдером, что уж тут поделаешь... Просто где-то я встречал описание delete как расширенный вариант вызова функции free. Так последняя вроде как вообще на вход void* получает... |
| Автор: archimed7592 21.5.2007, 14:48 | ||
|
| Автор: Anikmar 21.5.2007, 14:48 | ||
Вот именно - это меня и смутило. Одномерный массив приводится по-умолчанию к указателю на объект, именно поэтому, вызов соответствует стандарту - т.е. вызывается деструктор только для первого объекта. А вот вопрос: освобождается ли блок памяти. Ведь формально, в стандарте написано, что данная нотация применима к адресу объекта. Иначе - UB. Если мы этому оператору передаем имя массива, то он приводится к указателю, чем формально разрешает использование delete. Последний честно вызывает деструктор к первому объекту и освобождает память. Вопрос: Правильно ли он ее освобождает? |
| Автор: archimed7592 21.5.2007, 14:54 | ||||||||||
нет, возможно это мне одному режет глаз, когда говорят, что так делать "в принципе можно, если будешь сидеть на билдере, да ещё и такой-то версии, да ещё и такой-то сборки... и забудешь про возможность использования своего кода в других или более новых компиляторах..." мы же здесь общие вопросы обсуждаем, а не билдер... ежу понятно, что в билдере какое-то да поведение на этот счёт предусмотренно... но блин, это не значит, что нужно использовать эти знания о тараканах билдера при программировании... Добавлено через 14 минут и 40 секунд
|
| Автор: archimed7592 21.5.2007, 15:10 |
| другими словами: правильно он освобождает или нет is undefined |
| Автор: Anikmar 21.5.2007, 15:13 | ||||||
Да причем здесь Билдер? Я его как пример привел, потому, что просто работаю сейчас на нем. Меня вовсе не это интересовало, а вариант утечки памяти. Просто сразу в головоу примеры не приходят, но нутром чувствую, что возможны варианты смены формы этих операторов, по отношению именно к базовым типам. Одно дело, что так никто не делает и это режет глаза. Друго дело, что так делать категорически нельзя - так как вариант UB. Я так никогда не делаю, и в своем первом посте именно так написал:
Вы почему-то считаете, что я с вами спорю. Как раз наоборот, этот вопрос мне прсто интересен так как я его не очень хорошо представляю. Не отделбную же тему заводить - просто к случаю возник, вот я и поинтересовался. Я всегда считал, что форма [] отличается от обычной вызовом деструкторов. Но так как к базовым типам деструкторы не применяются, то и возник этот этот вопрос. Интересно, а что делает delete по отношению к указателю void*? Ведь по логике - 100% UB, а компилер даже ворнинг не дает на эту конструкцию... Странно. Добавлено через 3 минуты и 21 секунду А господин Страуструп добавляет путаницы (2-е издание):
|
| Автор: archimed7592 21.5.2007, 15:25 | ||||
во-первых, компилятор не обзан приводить ворнинги на каждое UB... во-вторых, на некоторые извращённые случаи UB вычислить на момент компиляции невозможно... |
| Автор: Daevaorn 21.5.2007, 15:27 | ||
нет. не тебе одному. А вот Anikmar'а совсем не понимаю. Что-то совсем не то говорит. Уже и стандарт ему привели, пора и успокоиться вроде как |
| Автор: Anikmar 21.5.2007, 15:49 | ||
Интересно, что это я такое не то говорю? Вообще-то я спрашиваю и ни с кем не спорю. А повышаю немного уровень своих знаний дабы избежать глупых ошибок. Я сам попросил перевести мне стандарт и указал пункты стандарта - так как мне маленько непонятен именно этот аспект. Во 2-м издании страуструпа есть описание формы оператора new, который просто выделяет блок памяти указанного размера. Описаны они так: void* operator new(size_t); void operator delete(void*); Соответственно у меня возник вопрос: если я выделяю под свои нужды некий буфер для чего угодно, то как правило использую форму new char[...] и delete [] Вот мне интересно стало, если для стандартных типов случайно забыть указать скобки. Если CodeGuard включен - никаких проблем, выловлю. А вот если нет - вариант UB меня сильно смущает - если оператор delete[] работает правильно, а оператор delete нет, то как они отличаются внутри? Ведь на вход им подается и в том и в другом случае просто указатель. И как отлавливать такие ошибки? Логичнее просится исключение а не UB. Кстати вышеприведенный пример Страуструпа у меня применить не получилось - не ест такую форму оператора new, хотя она приведена в хелпе. Daevaorn, еще раз повторяю, я ни скем не спорю! Просто мне интересно: как это устроено! И перед тем, как кинуть сюда пост, я как раз залез в стандарт - и меня смутила неоднозначность (как я его понял) приведенного пункта! Если оператору delete подсунуть неправильный указатель - все в порядке UB. Но delete ведь работает и с указателями void! И это говорит Страуструп (вроде как я к его мнению прислушиваюсь). Вот и возник вопрос: как тогда он работает. Ведь с указателем void форма [] абсурдна. А UB непонятно почему должен возникнуть... |
| Автор: Daevaorn 21.5.2007, 15:58 | ||||||||
да. и их так же можно и использовать как malloc
на моём микроконтролере память под массивы расположенна в другом оптимизированном для данной задачи месте. и мой менеджер памяти не проверяет тот ли блок ему подсунули, а для увеличения скорости просто освобождает её. если подсунуть не тот блок, то всё рушится. твой Builder уже надоел посмотри исходники своей стандартной библиотеки
к счатью он не стандарт |
| Автор: archimed7592 21.5.2007, 16:10 |
| угу... только #include <new> не забывать |
| Автор: Anikmar 21.5.2007, 16:12 |
Он не мой. Он Борландовский! Ну нету у меня ничего другого! И вообще - форум вещь добровольная. Я же не заставляю вас с паяльником в одном месте вести со мной диалог. Просто на конкретно моем компиляторе (не скажу каком |
| Автор: archimed7592 21.5.2007, 16:23 | ||
см. стандартный хэдер <new>... а ещё можешь почитать раздел 18.4 Dynamic memory management - там описано стандартное поведение этих "заменителей malloc/free" |
| Автор: Anikmar 21.5.2007, 16:35 | ||||
Это я уже читал утром. Видимо в выделенном блоке где-то хранится размер объекта, прикольный уффект на таком коде:
Т.е. память я выделяю под 1 объект. А когда вызываю delete[] (шифорот навыворот) то деструктор вызывается 15 раз! Видимо блок памяти выделяется с запасом, а размер объекта считается 1 байт. В общем ладно. Бог, с ними с этими операторами - все равно я никогда так не делал, всегда использовал адекватную связку. В общем лучше считать, что блок не освобождается (от греха подальше). |
| Автор: archimed7592 21.5.2007, 16:50 |
| Anikmar, как правило, размер выделенного блока хранится аккурат перед самим буффером... т. к. там мусор - не исключено, что будет вызван и миллион раз... |
| Автор: Anikmar 21.5.2007, 17:01 | ||
Откуда там мусор? Я же блок легальными средствами выделяю. Мне нигде не попадалось описание этого блока, но думаю, что там есть размер всего блока и размер элемента блока. В варианте замены malloc видимо размером объекта считается байт - вот он и вызывает деструктор соответственно количеству байтов в блоке. В общем экспериментировать надо с осторожностью. Вот когда приспичит собственный менеджер памяти писать, тогда и буду серьезно копать |
| Автор: archimed7592 21.5.2007, 17:12 |
| ну как откуда - а что, по адресу 0x123456 не мусор? не знаешь? ты легально получил кусок, но ты получил указатель именно на этот кусок... всё, что до и после этого куска нелегально и является мусором... |
| Автор: Anikmar 21.5.2007, 17:26 | ||
Не, это то понятно, я про блок управления памятью. Он содержит размер блока и видимо размер объекта, возможно какие-нибудь ссылки на предыдущий и следующий блок - не знаю. Остальное, естественно, мусор. Просто уже понятно, что по большой части вариант со скобками и без скорее всего блок освобождают по-любому (правда пользоваться этим не стоит). Оператор со скобками получает на вход 2 параметра: адрес блока и имя класса , для которого вызвать деструктор (либо адрес деструктора). Дальше он смотрит в блоке размер объекта ( в данном случае это 1 байт) и вызывает для каждого объекта деструктор, ничего больше не предполагая. А затем просто помечает блок как свободный. За пределы памяти вроде как раз не вылезает - четко в рамках блока действует. А дальше все зависит от деструктора. Мне кажется (не пробовал), что цинничное освобождение памяти, выделенной по new при помощи free также сработает - раз new по сути является оберткой для malloc. Другой вопрос на долго ли такая ситуация продлится - все в жизни модернизируется, поэтому лучше действовать по стандарту. Но зная схему работы уже лишних ошибок точно не сделаешь. Видимо поэтому и исключение выкинуть нельзя - так как известен только адрес блока и адрес функции деструктора, а вот размер объекта не подпихивается и проверить валидность сложно. |
| Автор: Daevaorn 21.5.2007, 17:32 | ||
мусор всё, и уж тем более какой-то там блок. archimed7592, забей. видимо человеку нравится заниматься гаданием |
| Автор: Anikmar 21.5.2007, 17:44 | ||
Да в общем-то тема уже полностью обсосана - я просто прикололся ради интереса (моего, естественно). И совсем не было у меня желания ,Daevaorn, вызвать у вас столько раздражения это вы правы, но и ограничивать себя в общении я как-то не особо собираюсь. Тут никто никого не заставляет отвечать - не нравятся мои "гадания" можно на них просто не реагировать "дескать пускай себе придурок всякую фигню пишет" В общем подвожу итог: свое любопытсво я полностью удовлетворил, archimed7592, спасибо за диалог и помощь в переводе стандарта. |
| Автор: archimed7592 21.5.2007, 17:49 |
| Anikmar, тебя интересует как по стандарту или как на практике? по стандарту UB - этот вопрос считаем закрытым... на практике... мой последний тебе пример: я тебе не так давно рассказывал про пулы... для динамического распределения маленьких объектов... вот представь, что, эффективности ради, new для блоков, размером не большим, чем 64 байта будут использоваться пулы... быстро, эффективно и т. д... сам понимаешь, что ни о каких malloc/free уже речи быть не может... как и о пренебрежении связок new/delete, new[]/delete[]... повторяю: это всего лишь пример, но ни что не мешает написать такой менеджер памяти и преподнести его как стандартный... т. о. в билдере следующей версии, если будет применена эта идея, работать твои догадки не будут... тебе это надо? если да, то в добрый путь в форум посвящённый этому компилятору... Добавлено через 1 минуту и 43 секунды твой интерес уместен, но не помешало бы постараться выслушать ответы и/или более чётко формулировать вопросы(если ответы не устраивают) |
| Автор: Anikmar 21.5.2007, 18:02 | ||||
Я что-то не припоминаю, что я с этим спорил. Я попросил помочь с переводом - так как сам был не уверен, что правильно перевел. Все мои эксперименты - чисто из познавательного любопытства. Как раз я в своих постах писал, что пренебрегать этим не следует, даже если какой-то транслятор отрабатывает правильно. Все мое любопытство заключалось только в схеме работы - из цикла "Как это работает". В общем тема закрыта, хотя думаю, что может возникнуть - я во многих книгах читал именно о таком поведении delete по отношению к стандартным классам, так что думаю кто-нибудь об этом заговорит.
Еще раз повторюсь, что я никогда не нарушал связки таких операторов, чего и остальным советую. Меня больше волновал вопрос поиска такого рода ошибки, если она не дай Бог вылезет. Достаточно трудоемко, на мой взгляд. Надо писать очень внимательно. Было бы лучше, конечно, чтобы влезало исключение - было бы как-то спокойнее на душе. Может в следующем стандарте это как раз и изменят. Не люблю UB - люблю, когда все четко можно/нельзя. Ладно, тему давайте закроем, а то на меня скоро матом уже будут ругаться |
| Автор: archimed7592 21.5.2007, 18:09 | ||
|
| Автор: Anikmar 21.5.2007, 18:18 | ||||||
Все дело в том, что как раз я и не понял, почему меня спорщиком решили объявить. Если посмотреть мой пост, с которого все началось, то там кроме сомнения ничего особо я не выражал, а вообще объяснял откуда такая точка зрения вообще есть:
Ага, еще предложите свой компилятор написать, который вместо UB исключение выплевывает! Не, можно и так, конечно, но пока я на CodeGuard остановлюсь (да простят меня за упоминание о билдере) Предлагаю, когда возникнет вопрос отлова ошибки утечки - создать новую тему! |
| Автор: archimed7592 21.5.2007, 18:29 | ||||||||
началось всё как раз более раннего поста
не знаю, что из себя представляет CodeGuard, но уверен, что он не панацея... в то время, как собственный менеджер памяти будет работать с любым компилятором и может быть намного более строг относительно пренебрежений стандартом(делаю выводы о том, как он молчал на очевидный UB). |
| Автор: Anikmar 21.5.2007, 18:45 | ||||||
После которого я признался, что Xenon прав и думал, что в общем-то спора нет.
Панацеи в нашей жизни нет. Но так говорить тоже нельзя:
Раз вы не знаете что это такое, то почему не простят?! Но в общем-то, если данную штуку рассматривать не запыляя глаза, что это ненавистный Билдер, то мне она видится полезной штуковиной именно для борьбы с утечками памяти. Уверен, что в студии нечто подобное тоже есть.
Да это понятно, это я так, прикололся - не проще ли компилер заставлять ругаться, чем заставлять программистов свои менеджеры памяти создавать. А по поводу Тут я не знаю, у меня же не все ворнинги включены. Если все включить - может и ругнется, попробую как-нибудь. К тому же очевидного UB я как раз не создал - я переприсвоил указатель, чтобы обмануть компилер. Если теоритически предстваить себе функцию, которая возвращает строку, память под которую сама выделяет (в общем то примерный вопрос этой темы), то в описании функции необходимо точно предупредить каким образом удалять данный блок - со скобками или без, ведь он может выделиться как char *Buf = new char[100]; и просто как char *Buf = (char*) new(100); Последнее выглядит несколько извращенно, но допустимо. Соответственно, если такая функция чужая, и ее разработчик забыл указать, что удалять строку надо delete[], а не delete - вот тут как раз и возникнет UB, который мне не нравится. Было бы абсалютно логично, что блок должен удалиться по-любому, а вот вызов деструкторов - по желанию (собственно почему я и засомневался, правильно я понял стандарт или нет, английский слабоват). В общем баянище у нас получился - никак не оторваться |
| Автор: Dov 21.5.2007, 20:29 | ||||||||||||
INHazeR, а ты попробуй адрес указателя передавать. Может чего и выйдет. Насколько я понял, у тебя есть какой-то указатель. Например, есть такой код:
Добавь ф-цию:
и вызывай так:
Добавлено через 4 минуты и 35 секунд Если это С++, то можно ещё так:
|
| Автор: archimed7592 21.5.2007, 22:40 | ||
было бы абсолютно логично писать по правилам... юзать smart pointer'ы, контейнеры и прочую лабуду, минимизирующую кол-во такого рода ошибок... ;) |
| Автор: Anikmar 21.5.2007, 22:52 | ||||
Ну да, пример не совсем удачный, я забыл, что там надо operator добавлять
Истественно. Я просто про сторонню.ю функцию. Которая написана кем-то другим, и по возвращаемому значению сложно определить одиночный это указатель или массив. Допустим, функция достаточно важная, самому писать ее долго, как она выделяет память неясно, но ее надо освободить. Вот я и прикидываю, есть ли способ это определить имея на руках только указатель... |
| Автор: archimed7592 22.5.2007, 02:00 |
| в общем случае - нет... а вообще, "важная" ф-ция обязательно задокументирует способ, которым нужно вызывающей стороне освобождать память т. к. выделить её можно туевой хучей способов... |
| Автор: Anikmar 22.5.2007, 09:01 | ||
Ваши слова - да Богу в уши. Помню времена MS-DOS. Книжка у меня была - Описание недокументированных прерываний DOS. И ведь куча программ была, которые этим пользовались. ИМХО Это одна из дырок стандарта. Думаю ее будут потом исправлять. Если нужно держать связку операторов четко - должен быть способ узнать тип применяемого оператора. Если это пишет один человек - ерунда, сам должен следить. А вот если баг в описании чужой функции, да еще исходник недоступен. Тут ведь совместимость на двоичном уровне идет. Ладно, вода все это. Вот когда такая ситуация возникнет - будем конкретно ее обсуждать. Сейчас у меня таких проблем нет, утечка памяти достаточно редкий случай - благо на этот счет инструментария разного достаточно. |
| Автор: v_nikolaev 24.5.2007, 10:38 | ||||||
а почему не написать красивее?
|
| Автор: Fazil6 24.5.2007, 11:05 |
потому что это не одно и тоже. Твой код совершенно другое будет делать |
| Автор: archimed7592 24.5.2007, 11:08 |
| ну не совершенно... всего-то p на один эл-т дальше будет сдвинут... |
| Автор: v_nikolaev 24.5.2007, 11:11 | ||
насколько я понимаю, разница тут только в том, что я сделал лишний раз ++. *p++ - сначала происхоит присвоение в нужную память, а потом ++ к указателю. archimed7592 |
| Автор: Fazil6 24.5.2007, 11:20 | ||
нет. Это унарные операторы. Сначала ++ , потом *. |
| Автор: archimed7592 24.5.2007, 11:21 |
| Fazil6, ты согласен, что *p++ эквивалентно *(p++)? вытекает из приоритетов операторов... |
| Автор: Fazil6 24.5.2007, 11:22 | ||||
ага, разница невелика (всего один элемент) и можно на эту разницу забить? Вобщем действительно , какая уж разница какой элемент массива менять... Особенно когда p на последний элемент указывает. Добавлено @ 11:24
согласен, тока в примере *p++ = 5 и *(++p) = 5 , а это не эквивалентно |
| Автор: archimed7592 24.5.2007, 11:30 | ||||
| никто не говорит, что забить можно... просто в данном конкретном случае никакой погоды это не делает... тем более, что, с тем же успехом, в последней строке можно не писать ++... просто этот сдвиг не означает, что код делает совершенно другое...
блин, эквивалентны вот эти два примера в целом... а о построчной эквивалентности никто не утверждал
|
| Автор: Fazil6 24.5.2007, 11:30 | ||
Непоняли друг друга. Я немного не то хотел сказать. Я имел в виду, что пост и преинкремент разные результаты дадут и * применяется к разным адресам |
| Автор: archimed7592 24.5.2007, 11:34 |
| я отлично понял, что ты хотел сказать... вопрос только к чему ты это сказал? |
| Автор: Fazil6 24.5.2007, 11:34 |
а, ну да... вцелом одно и тоже. Я не понял |
| Автор: v_nikolaev 24.5.2007, 12:04 |
| и вообще это стандартный способ работы с массивом, так что откуда сомнения? ещё добавлю, что лишний ++ компилятором скорее всего проигнорируется, как мёртвый код, а если вдруг он живой, то тогда он не лишний |
| Автор: JackYF 24.5.2007, 13:08 |
G++, например, выдаст варнинг, скорее всего. |
| Автор: v_nikolaev 24.5.2007, 13:14 | ||
это gcc в смысле? что-то я сомневаюсь, что выдаст, хотя... вдруг я проинкрементил указатель, а присвоить куда надо что надо забыл мёртвый код - в порядке вещеё, так же как и оптимизация в компиляторе а если оптимизирующий компилятор будет сообщать такие штуки, а не молча работать, ему гордиться нечем будет |
| Автор: archimed7592 24.5.2007, 13:19 |
| ну на неюзанные переменные он варнинги фигачит... |
| Автор: v_nikolaev 24.5.2007, 13:35 | ||
неюзанные переменные могут быть связаны с ошибкой в логике программы. а лишний код можно писать из удобства. и потом, это в разные фазы работы компилятора анализ на мёртвый код и на неюзаынные переменные, имхо, происходит. |
| Автор: Ангелочек 23.10.2008, 23:52 | ||||
| Есть функция которая изменяет параметры двух массивов. например
Есть численные значения этих массивов, которые нельзя сгенерировать. Мне не важно статические или динамические массивы. Если я обьяляю статику, то появляется ошибка конвертации float ** в float[][n] иначе ошибка в самой иницализации. Инициализирую в виде
Вопрос: Как передать инициализированный массив. Иницилизировать поэлементно не хочется - много их. ЗЫ PS Всем ответившим заранее спасибо. |
| Автор: J0ker 24.10.2008, 01:38 |
| Ангелочек, некрофильствуем понемногу? |
| Автор: J0ker 24.10.2008, 01:56 | ||
это важно компилятору для статического массивов можно объявить:
при этом n должна быть константой 2модератор наверное надо в новую тему вынести, а то топик уже попахивает |
| Автор: Lycifer 29.10.2008, 15:17 |
| собственно const int sizeStr = ???; int newSizeStr = sizeStr; char* str = new char[sizeStr]; someFunction(str, newSizeStr);//someFunction(str, &newSizeStr); int someFunction(char* str, int& newSizeStr)//someFunction(char* str, int* newSizeStr) { int result= 0; return result; } str - буфер newSizeStr - in -размер выделенной памяти out - сколько памяти занял result - будет результат выполнения если всё хорошо то равен 0 если нет то не равен ноль |