![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
INHazeR |
|
||||
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 8.12.2006 Репутация: нет Всего: нет |
имеется некая функция
Необходимо, чтобы после выполнения данной функции по адресу s находилась некая строка (массив char), а по адресу p - массив целых чисел. В случае с целыми числами сделал просто
т.к. было известно, что возвращаемый массив всегда из 3-х чисел. При этом, приходится создавать этот массив вне функции, до ее вызова. В случае с массивом чаров, даже при предварительном создании массивов соответствующей длины, вызов внутри Foo функций itoa ведет к ошибкам... вроде бы как память не выделена. В общем, как по этим указателям корректно создать и заполнить соотвествующие массивы? Заранее спасибо. |
||||
|
|||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
вероятно проблема в нуль-символе, выделяйте память на 1 больше чем фактически требуется, в конец добавляйте нуль-символ ('\0' или просто 0), по нему функции определяют конец строки. |
|||
|
||||
INHazeR |
|
|||
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 8.12.2006 Репутация: нет Всего: нет |
Пробовал выделять больше памяти, эффект тот же..
Интересует общая технология выделения памяти и инициализация таких массивов в данном случае... ![]() |
|||
|
||||
zkv |
|
||||||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
а это делали:
ммм.. Какая такая общая технология? Это что ли:
? |
||||||
|
|||||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
zkv, ?
Или это ирония была? ![]() Это сообщение отредактировал(а) Xenon - 21.5.2007, 01:59 |
|||
|
||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
||||
|
||||
jonie |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 15 Всего: 118 |
в общем могу, конечно, и ошибаться.... -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Нет, вы не ошибаетесь. Но лучше все равно вызывать delete[]. Чтобы была железная привычка. Это полезно, если при написании программы захочется использовать не простой тип, а собственный. И можно забыть, что освободждалась память "по-простому", появится утечка. |
|||
|
||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
new/delete и new[]/delete[] - все другие комбинации UB и ошибка всегда. |
|||
|
||||
Anikmar |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Если брать Билдер с запущенным CodeGuardom, то на простых типах
Ошибки утечки не возникает, только предупреждение. А если использовать свой тип - то возникает утечка. Тем не менее так делать не надо, разные компиляторы возможно ведут себя по-разному. Хотя я не помню что написано в стандарте по этому поводу, но точно помню, что в литературе по простым типам иногда делалась поблажка - может быть поэтому такое мнение и витает, что на простых типах ошибки нет. |
||||
|
|||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Начинается ... Где-то мы уже об этом спорили с Earnest
![]() ![]() Даже тему нашел http://forum.vingrad.ru/forum/topic-144984/15.html |
|||
|
||||
INHazeR |
|
|||
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 8.12.2006 Репутация: нет Всего: нет |
Гм. Все-таки непонятно, как по данному адресу (переданному в параметре функции) выделить память и заполнить ее значениями. Варианты типа
void Foo(char* s, int* p)
не годятся, насколько я понимаю, так как адрес (s) сам по себе неизменен, этот указатель создали где-то вне функции и передали сюда, так что присваивать ему новое значение внутри функции бессмысленно, разве не так? При выходе из функции он снова примет прежнее значение, а выделенная нами память останется мертвым грузом где-то в куче. По-моему, необходимо выделить память по заданному адресу, а не найти память и присвоить адрес начального байта этой памяти в указатель... или я ошибаюсь? |
|||
|
||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
INHazeR,
|
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Ничего не начинается, вы что думаете, что я буду отстаивать такую точку зрения? Я просто говорю про конкретное поведение того же Билдера, думаю, в остальных компиляторах будет также - блок удалится, но так делать НЕ НАДО. Можно, конечно, асмовский код посмотреть. Но думаю, что с точки зрения менеджера памяти - ему все равно, что в этом блоке памяти находится, он его будет идентифицировать по адресу, поэтому удалить должен. Но это - все равно пурга, если выделили память new[] то удалять надо delete[] без всяких там предположений. Так что, Xenon, вы полностью правы и спорить я даже не собирался - но в литературе, действительно, встречается такая ерундень - типа для базовых типов большого значения не имеет delete использовать или delete[]. К сожалению моего английского не хватает точно перевести соответствующую главу стандарта, но мне кажется что именно UB там не значится (но спорить не буду - не уверен). |
|||
|
||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Anikmar, ну просто предпосылки к спору с Daevaorn были, поэтому я уже воскинул руки к небу, а то уже которая тема религиозных войн ... наболело просто
![]() А которая глава стандарта? Я просто в стандарте не смотрел. |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
5.4.1 и 5.4.2. Кстати, вот еще доказательство, что менеджеру памяти по барабану, что находится в блоке - такой код работает без проблем и CodeGuard молчит как рыба об лед:
|
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
фраза аналогична следующей: если взять компьютер васи пупкина, находящийся в зимбабве, то утечки не будет...
ну да, может и не будет... только вот зачем делать такие высказывания не совсем понятно ![]() Добавлено через 8 минут и 26 секунд 5.3.5 -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Anikmar |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Почему не понятно? jonie высказал мнение, с котороым в общем то я согласен, и спор Xenon-а и Earnest я посмотрел - на самом деле однозначного мнения не возникло. Я посмотрел стандарт, но моего английского не хватило - вот я и решил подождать, когда Xenon посмотрит стандарт (я так понимаю он сильнее меня в английском) и скажет однозначное мнение. А по поводу Билдера и т.п. - я просто не смотрел другие компиляторы, а это мнение лично видел по-моему у того же Архангельского: если массив выделяется под простые типы, то оператор delete освободит блок и утечки не будет. Если CodeGuard отключить - то все работает нормально, блок освобождается, ругани не происходит. Если включить, то на простых типах CodeGuard выдает предупреждение на несоответствии способа выделения и освобождения памяти, а вот на собственных - ругается капитально и кричит об утечке. На самом деле, я считаю что такое высказывание нужно было сделать - так как мнение о том, что для стандартных типов не обязательно использовать [] достаточно распространенное, я у многих его встречал и сам лично читал в литературе. Но мнения это мнения, а вот что говорит по этому поводу стандарт было бы интересно узнать. Лично я всегда использую одну и ту же форму выделения памяти чего и другим настоятельно рекомендую. Но вариант UB в этом случае тоже как-то плоховато смотрится - это все-таки вещь достаточно ответственная. И от оператора delete ожидается все-таки освобождение памяти. Если менеджер памяти четко знает как выделен блок, то почему тогда не выкинуть исключение? Наверное менеджера ничего кроме указателя на блок не интересует, тогда UB просто нелогичен... В общем пошел флуд, размышления о вечном ![]()
Сравнение неадекватное. Билдер является нормальным компилятором, со своими тараканами, но тут на вкус и на цвет... мне кажется компиляторов без недостатков не бывает. Я вообще и не собирался спорить - это был не спор, а попытка выяснить все-таки: как стандарт предписывает вести себя оператору delete. Конкретно Билдер ведет себя так. Если в стандарте написано UB - значит Билдер придерживается стандарта. Если написано, что должен освобождать блок - значит тоже придерживается. ![]() |
||||
|
|||||
archimed7592 |
|
||||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
![]() может больше не будем даже упоминать даже о возможности такого в билдере с тараканами? Добавлено через 4 минуты и 15 секунд эээ... хотя тут сказано, что нельзя делать new->delete[] по поводу new[]->delete чуть выше:
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
||||
|
|||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Я вообще-то ни слова не говорил про второй вариант нотации. Т.е., что можно использовать delete[] к объекту выделенному просто new. Это и ежу понятно - какие деструкторы он вызовет? С этим то как раз все ясно. Я говорил, что интересно бы узнать, как должен по-стандарту вести себя delete, примененный к объекту, выделенному new[] По поводу тараканов: Вариант UB предусматривает любое поведение - так что Билдер по-любому ведет себя соответствующим стандарту образом. И почему собственно мы должны не упоминать о специфике поведения конкретного транслятора? Сейчас возникло обсуждение реализации конкретного участка стандарта, я пользуюсь билдером, что уж тут поделаешь... Просто где-то я встречал описание delete как расширенный вариант вызова функции free. Так последняя вроде как вообще на вход void* получает... |
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Вот именно - это меня и смутило. Одномерный массив приводится по-умолчанию к указателю на объект, именно поэтому, вызов соответствует стандарту - т.е. вызывается деструктор только для первого объекта. А вот вопрос: освобождается ли блок памяти. Ведь формально, в стандарте написано, что данная нотация применима к адресу объекта. Иначе - UB. Если мы этому оператору передаем имя массива, то он приводится к указателю, чем формально разрешает использование delete. Последний честно вызывает деструктор к первому объекту и освобождает память. Вопрос: Правильно ли он ее освобождает? |
|||
|
||||
archimed7592 |
|
||||||||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
имхо, такие заявления будут полезны в форуме, посвященном билдеру... нет, возможно это мне одному режет глаз, когда говорят, что так делать "в принципе можно, если будешь сидеть на билдере, да ещё и такой-то версии, да ещё и такой-то сборки... и забудешь про возможность использования своего кода в других или более новых компиляторах..." мы же здесь общие вопросы обсуждаем, а не билдер... ежу понятно, что в билдере какое-то да поведение на этот счёт предусмотренно... но блин, это не значит, что нужно использовать эти знания о тараканах билдера при программировании... Добавлено через 14 минут и 40 секунд
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
||||||||
|
|||||||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
другими словами: правильно он освобождает или нет is undefined
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Anikmar |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Да причем здесь Билдер? Я его как пример привел, потому, что просто работаю сейчас на нем. Меня вовсе не это интересовало, а вариант утечки памяти. Просто сразу в головоу примеры не приходят, но нутром чувствую, что возможны варианты смены формы этих операторов, по отношению именно к базовым типам. Одно дело, что так никто не делает и это режет глаза. Друго дело, что так делать категорически нельзя - так как вариант UB. Я так никогда не делаю, и в своем первом посте именно так написал:
Вы почему-то считаете, что я с вами спорю. Как раз наоборот, этот вопрос мне прсто интересен так как я его не очень хорошо представляю. Не отделбную же тему заводить - просто к случаю возник, вот я и поинтересовался. Я всегда считал, что форма [] отличается от обычной вызовом деструкторов. Но так как к базовым типам деструкторы не применяются, то и возник этот этот вопрос. Интересно, а что делает delete по отношению к указателю void*? Ведь по логике - 100% UB, а компилер даже ворнинг не дает на эту конструкцию... Странно. Добавлено через 3 минуты и 21 секунду А господин Страуструп добавляет путаницы (2-е издание):
|
||||
|
|||||
archimed7592 |
|
||||||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
||||||
|
|||||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
нет. не тебе одному. А вот Anikmar'а совсем не понимаю. Что-то совсем не то говорит. Уже и стандарт ему привели, пора и успокоиться вроде как ![]() |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Интересно, что это я такое не то говорю? Вообще-то я спрашиваю и ни с кем не спорю. А повышаю немного уровень своих знаний дабы избежать глупых ошибок. Я сам попросил перевести мне стандарт и указал пункты стандарта - так как мне маленько непонятен именно этот аспект. Во 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 |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
да. и их так же можно и использовать как malloc
на моём микроконтролере память под массивы расположенна в другом оптимизированном для данной задачи месте. и мой менеджер памяти не проверяет тот ли блок ему подсунули, а для увеличения скорости просто освобождает её. если подсунуть не тот блок, то всё рушится. твой Builder уже надоел ![]() посмотри исходники своей стандартной библиотеки
к счатью он не стандарт Это сообщение отредактировал(а) Daevaorn - 21.5.2007, 16:18 |
||||||||
|
|||||||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
угу... только #include <new> не забывать
![]() -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Он не мой. Он Борландовский! Ну нету у меня ничего другого! ![]() ![]() И вообще - форум вещь добровольная. Я же не заставляю вас с паяльником в одном месте вести со мной диалог. ![]() Просто на конкретно моем компиляторе (не скажу каком ![]() |
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
см. стандартный хэдер <new>... а ещё можешь почитать раздел 18.4 Dynamic memory management - там описано стандартное поведение этих "заменителей malloc/free" -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Anikmar |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Это я уже читал утром. Видимо в выделенном блоке где-то хранится размер объекта, прикольный уффект на таком коде:
Т.е. память я выделяю под 1 объект. А когда вызываю delete[] (шифорот навыворот) то деструктор вызывается 15 раз! Видимо блок памяти выделяется с запасом, а размер объекта считается 1 байт. В общем ладно. Бог, с ними с этими операторами - все равно я никогда так не делал, всегда использовал адекватную связку. В общем лучше считать, что блок не освобождается (от греха подальше). ![]() |
||||
|
|||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
Anikmar, как правило, размер выделенного блока хранится аккурат перед самим буффером... т. к. там мусор - не исключено, что будет вызван и миллион раз...
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Откуда там мусор? Я же блок легальными средствами выделяю. Мне нигде не попадалось описание этого блока, но думаю, что там есть размер всего блока и размер элемента блока. В варианте замены malloc видимо размером объекта считается байт - вот он и вызывает деструктор соответственно количеству байтов в блоке. В общем экспериментировать надо с осторожностью. Вот когда приспичит собственный менеджер памяти писать, тогда и буду серьезно копать ![]() |
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
ну как откуда - а что, по адресу 0x123456 не мусор? не знаешь?
![]() ![]() ты легально получил кусок, но ты получил указатель именно на этот кусок... всё, что до и после этого куска нелегально и является мусором... -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Не, это то понятно, я про блок управления памятью. Он содержит размер блока и видимо размер объекта, возможно какие-нибудь ссылки на предыдущий и следующий блок - не знаю. Остальное, естественно, мусор. Просто уже понятно, что по большой части вариант со скобками и без скорее всего блок освобождают по-любому (правда пользоваться этим не стоит). Оператор со скобками получает на вход 2 параметра: адрес блока и имя класса , для которого вызвать деструктор (либо адрес деструктора). Дальше он смотрит в блоке размер объекта ( в данном случае это 1 байт) и вызывает для каждого объекта деструктор, ничего больше не предполагая. А затем просто помечает блок как свободный. За пределы памяти вроде как раз не вылезает - четко в рамках блока действует. А дальше все зависит от деструктора. Мне кажется (не пробовал), что цинничное освобождение памяти, выделенной по new при помощи free также сработает - раз new по сути является оберткой для malloc. Другой вопрос на долго ли такая ситуация продлится - все в жизни модернизируется, поэтому лучше действовать по стандарту. Но зная схему работы уже лишних ошибок точно не сделаешь. Видимо поэтому и исключение выкинуть нельзя - так как известен только адрес блока и адрес функции деструктора, а вот размер объекта не подпихивается и проверить валидность сложно. |
|||
|
||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
мусор всё, и уж тем более какой-то там блок. archimed7592, забей. видимо человеку нравится заниматься гаданием ![]() |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Да в общем-то тема уже полностью обсосана - я просто прикололся ради интереса (моего, естественно). И совсем не было у меня желания ,Daevaorn, вызвать у вас столько раздражения ![]() это вы правы, но и ограничивать себя в общении я как-то не особо собираюсь. Тут никто никого не заставляет отвечать - не нравятся мои "гадания" можно на них просто не реагировать "дескать пускай себе придурок всякую фигню пишет" ![]() В общем подвожу итог: свое любопытсво я полностью удовлетворил, archimed7592, спасибо за диалог и помощь в переводе стандарта. |
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
Anikmar, тебя интересует как по стандарту или как на практике? по стандарту UB - этот вопрос считаем закрытым...
на практике... мой последний тебе пример: я тебе не так давно рассказывал про пулы... для динамического распределения маленьких объектов... вот представь, что, эффективности ради, new для блоков, размером не большим, чем 64 байта будут использоваться пулы... быстро, эффективно и т. д... сам понимаешь, что ни о каких malloc/free уже речи быть не может... как и о пренебрежении связок new/delete, new[]/delete[]... повторяю: это всего лишь пример, но ни что не мешает написать такой менеджер памяти и преподнести его как стандартный... т. о. в билдере следующей версии, если будет применена эта идея, работать твои догадки не будут... тебе это надо? если да, то в добрый путь в форум посвящённый этому компилятору... Добавлено через 1 минуту и 43 секунды твой интерес уместен, но не помешало бы постараться выслушать ответы и/или более чётко формулировать вопросы(если ответы не устраивают) -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Anikmar |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Я что-то не припоминаю, что я с этим спорил. Я попросил помочь с переводом - так как сам был не уверен, что правильно перевел. Все мои эксперименты - чисто из познавательного любопытства. Как раз я в своих постах писал, что пренебрегать этим не следует, даже если какой-то транслятор отрабатывает правильно. Все мое любопытство заключалось только в схеме работы - из цикла "Как это работает". В общем тема закрыта, хотя думаю, что может возникнуть - я во многих книгах читал именно о таком поведении delete по отношению к стандартным классам, так что думаю кто-нибудь об этом заговорит.
Еще раз повторюсь, что я никогда не нарушал связки таких операторов, чего и остальным советую. Меня больше волновал вопрос поиска такого рода ошибки, если она не дай Бог вылезет. Достаточно трудоемко, на мой взгляд. Надо писать очень внимательно. Было бы лучше, конечно, чтобы влезало исключение - было бы как-то спокойнее на душе. Может в следующем стандарте это как раз и изменят. Не люблю UB - люблю, когда все четко можно/нельзя. Ладно, тему давайте закроем, а то на меня скоро матом уже будут ругаться ![]() |
||||
|
|||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
эээ... писать свой менеджер памяти, который будет медленным, но будет отслеживать и неправильные связки usual/[] и многократное удаление одного блока и НЕудаление некоторых блоков и вообще чё душе угодно... -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Все дело в том, что как раз я и не понял, почему меня спорщиком решили объявить. Если посмотреть мой пост, с которого все началось, то там кроме сомнения ничего особо я не выражал, а вообще объяснял откуда такая точка зрения вообще есть: Ага, еще предложите свой компилятор написать, который вместо UB исключение выплевывает! ![]() Не, можно и так, конечно, но пока я на CodeGuard остановлюсь (да простят меня за упоминание о билдере) ![]() Предлагаю, когда возникнет вопрос отлова ошибки утечки - создать новую тему! |
|||
|
||||
archimed7592 |
|
||||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
началось всё как раз более раннего поста ну да ладно... никто тебя спорщиком не объявляет...
![]() не знаю, что из себя представляет CodeGuard, но уверен, что он не панацея... в то время, как собственный менеджер памяти будет работать с любым компилятором и может быть намного более строг относительно пренебрежений стандартом(делаю выводы о том, как он молчал на очевидный UB). -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
||||
|
|||||
Anikmar |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
После которого я признался, что Xenon прав и думал, что в общем-то спора нет.
Панацеи в нашей жизни нет. Но так говорить тоже нельзя:
Раз вы не знаете что это такое, то почему не простят?! ![]() Но в общем-то, если данную штуку рассматривать не запыляя глаза, что это ненавистный Билдер, то мне она видится полезной штуковиной именно для борьбы с утечками памяти. Уверен, что в студии нечто подобное тоже есть. Да это понятно, это я так, прикололся - не проще ли компилер заставлять ругаться, чем заставлять программистов свои менеджеры памяти создавать. А по поводу Тут я не знаю, у меня же не все ворнинги включены. Если все включить - может и ругнется, попробую как-нибудь. К тому же очевидного UB я как раз не создал - я переприсвоил указатель, чтобы обмануть компилер. Если теоритически предстваить себе функцию, которая возвращает строку, память под которую сама выделяет (в общем то примерный вопрос этой темы), то в описании функции необходимо точно предупредить каким образом удалять данный блок - со скобками или без, ведь он может выделиться как char *Buf = new char[100]; и просто как char *Buf = (char*) new(100); Последнее выглядит несколько извращенно, но допустимо. Соответственно, если такая функция чужая, и ее разработчик забыл указать, что удалять строку надо delete[], а не delete - вот тут как раз и возникнет UB, который мне не нравится. Было бы абсалютно логично, что блок должен удалиться по-любому, а вот вызов деструкторов - по желанию (собственно почему я и засомневался, правильно я понял стандарт или нет, английский слабоват). В общем баянище у нас получился - никак не оторваться ![]() |
||||
|
|||||
Dov |
|
||||||||||||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
INHazeR, а ты попробуй адрес указателя передавать. Может чего и выйдет. Насколько я понял, у тебя есть какой-то указатель. Например, есть такой код:
Добавь ф-цию:
и вызывай так:
Добавлено через 4 минуты и 35 секунд Если это С++, то можно ещё так:
-------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
||||||||||||
|
|||||||||||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
ты наверное имел ввиду operator new (100) (иначе, просто не скомпилируется, имхо)... тогда нужен ни delete, ни delete [], а operator delete... ![]()
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Anikmar |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Ну да, пример не совсем удачный, я забыл, что там надо operator добавлять
Истественно. Я просто про сторонню.ю функцию. Которая написана кем-то другим, и по возвращаемому значению сложно определить одиночный это указатель или массив. Допустим, функция достаточно важная, самому писать ее долго, как она выделяет память неясно, но ее надо освободить. Вот я и прикидываю, есть ли способ это определить имея на руках только указатель... |
||||
|
|||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Ваши слова - да Богу в уши. Помню времена MS-DOS. Книжка у меня была - Описание недокументированных прерываний DOS. И ведь куча программ была, которые этим пользовались. ИМХО Это одна из дырок стандарта. Думаю ее будут потом исправлять. Если нужно держать связку операторов четко - должен быть способ узнать тип применяемого оператора. Если это пишет один человек - ерунда, сам должен следить. А вот если баг в описании чужой функции, да еще исходник недоступен. Тут ведь совместимость на двоичном уровне идет. Ладно, вода все это. Вот когда такая ситуация возникнет - будем конкретно ее обсуждать. Сейчас у меня таких проблем нет, утечка памяти достаточно редкий случай - благо на этот счет инструментария разного достаточно. |
|||
|
||||
v_nikolaev |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 38 Регистрация: 6.5.2007 Репутация: нет Всего: нет |
а почему не написать красивее?
|
||||||
|
|||||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
ну не совершенно... всего-то p на один эл-т дальше будет сдвинут...
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
v_nikolaev |
|
|||
Новичок Профиль Группа: Участник Сообщений: 38 Регистрация: 6.5.2007 Репутация: нет Всего: нет |
насколько я понимаю, разница тут только в том, что я сделал лишний раз ++. *p++ - сначала происхоит присвоение в нужную память, а потом ++ к указателю. archimed7592 ![]() Это сообщение отредактировал(а) v_nikolaev - 24.5.2007, 11:17 |
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
Fazil6,
![]() ты согласен, что *p++ эквивалентно *(p++)? вытекает из приоритетов операторов... Это сообщение отредактировал(а) archimed7592 - 24.5.2007, 11:22 -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
ага, разница невелика (всего один элемент) и можно на эту разницу забить? Вобщем действительно , какая уж разница какой элемент массива менять... Особенно когда p на последний элемент указывает. Добавлено @ 11:24
согласен, тока в примере *p++ = 5 и *(++p) = 5 , а это не эквивалентно Это сообщение отредактировал(а) Fazil6 - 24.5.2007, 11:25 |
||||
|
|||||
archimed7592 |
|
||||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
никто не говорит, что забить можно... просто в данном конкретном случае никакой погоды это не делает... тем более, что, с тем же успехом, в последней строке можно не писать ++...
просто этот сдвиг не означает, что код делает совершенно другое...
блин, эквивалентны вот эти два примера в целом... а о построчной эквивалентности никто не утверждал
Это сообщение отредактировал(а) archimed7592 - 24.5.2007, 11:30 -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
||||
|
|||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
я отлично понял, что ты хотел сказать... вопрос только к чему ты это сказал?
![]() -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
v_nikolaev |
|
|||
Новичок Профиль Группа: Участник Сообщений: 38 Регистрация: 6.5.2007 Репутация: нет Всего: нет |
и вообще это стандартный способ работы с массивом, так что откуда сомнения?
ещё добавлю, что лишний ++ компилятором скорее всего проигнорируется, как мёртвый код, а если вдруг он живой, то тогда он не лишний ![]() |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
G++, например, выдаст варнинг, скорее всего. |
|||
|
||||
v_nikolaev |
|
|||
Новичок Профиль Группа: Участник Сообщений: 38 Регистрация: 6.5.2007 Репутация: нет Всего: нет |
это gcc в смысле? что-то я сомневаюсь, что выдаст, хотя... вдруг я проинкрементил указатель, а присвоить куда надо что надо забыл ![]() мёртвый код - в порядке вещеё, так же как и оптимизация в компиляторе ![]() а если оптимизирующий компилятор будет сообщать такие штуки, а не молча работать, ему гордиться нечем будет ![]() Это сообщение отредактировал(а) v_nikolaev - 24.5.2007, 13:16 |
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
ну на неюзанные переменные он варнинги фигачит...
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
v_nikolaev |
|
|||
Новичок Профиль Группа: Участник Сообщений: 38 Регистрация: 6.5.2007 Репутация: нет Всего: нет |
неюзанные переменные могут быть связаны с ошибкой в логике программы. а лишний код можно писать из удобства. и потом, это в разные фазы работы компилятора анализ на мёртвый код и на неюзаынные переменные, имхо, происходит. |
|||
|
||||
Ангелочек |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 53 Регистрация: 17.6.2006 Репутация: нет Всего: 2 |
Есть функция которая изменяет параметры двух массивов.
например
Есть численные значения этих массивов, которые нельзя сгенерировать. Мне не важно статические или динамические массивы. Если я обьяляю статику, то появляется ошибка конвертации float ** в float[][n] иначе ошибка в самой иницализации. Инициализирую в виде
Вопрос: Как передать инициализированный массив. Иницилизировать поэлементно не хочется - много их. ЗЫ ![]() PS Всем ответившим заранее спасибо. |
||||
|
|||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 4 Всего: 14 |
Ангелочек, некрофильствуем понемногу?
![]() |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 4 Всего: 14 |
это важно компилятору для статического массивов можно объявить:
при этом n должна быть константой 2модератор наверное надо в новую тему вынести, а то топик уже попахивает ![]() |
|||
|
||||
Lycifer |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 144 Регистрация: 4.11.2007 Репутация: нет Всего: нет |
собственно
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 если нет то не равен ноль |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |