Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Инициализация указателей, переданных в параметрах, запутался 
:(
    Опции темы
Anikmar
Дата 21.5.2007, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(Xenon @  21.5.2007,  12:42 Найти цитируемый пост)
А которая глава стандарта? Я просто в стандарте не смотрел. 

5.4.1 и 5.4.2.
Кстати, вот еще доказательство, что менеджеру памяти по барабану, что находится в блоке - такой код работает без проблем и CodeGuard молчит как рыба об лед:
Код

    int *BMas;
    char *BBMas;
            
    BMas = new int[50];
    BBMas = (char*)BMas;

    delete []BBMas;

PM MAIL ICQ   Вверх
archimed7592
Дата 21.5.2007, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(Anikmar @  21.5.2007,  10:42 Найти цитируемый пост)
Если брать Билдер
фраза аналогична следующей: если взять компьютер васи пупкина, находящийся в зимбабве, то утечки не будет...
ну да, может и не будет... только вот зачем делать такие высказывания не совсем понятно smile

Добавлено через 8 минут и 26 секунд
Цитата(Xenon @  21.5.2007,  12:42 Найти цитируемый пост)
А которая глава стандарта?
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
PM Jabber   Вверх
Anikmar
Дата 21.5.2007, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(archimed7592 @  21.5.2007,  13:52 Найти цитируемый пост)
только вот зачем делать такие высказывания не совсем понятно  

Почему не понятно?
jonie высказал мнение, с котороым в общем то я согласен, и спор Xenon-а и Earnest я посмотрел - на самом деле однозначного мнения не возникло. Я посмотрел стандарт, но моего английского не хватило - вот я и решил подождать, когда Xenon посмотрит стандарт (я так понимаю он сильнее меня в английском) и скажет однозначное мнение.

А по поводу Билдера и т.п. - я просто не смотрел другие компиляторы, а это мнение лично видел по-моему у того же Архангельского: если массив выделяется под простые типы, то оператор delete освободит блок и утечки не будет.

Если CodeGuard отключить - то все работает нормально, блок освобождается, ругани не происходит.
Если включить, то на простых типах CodeGuard выдает предупреждение на несоответствии способа выделения и освобождения памяти, а вот на собственных - ругается капитально и кричит об утечке.

На самом деле, я считаю что такое высказывание нужно было сделать - так как мнение о том, что для стандартных типов не обязательно использовать [] достаточно распространенное, я у многих его встречал и сам лично читал в литературе. Но мнения это мнения, а вот что говорит по этому поводу стандарт было бы интересно узнать. 

Лично я всегда использую одну и ту же форму выделения памяти чего и другим настоятельно рекомендую. Но вариант UB в этом случае тоже как-то плоховато смотрится - это все-таки вещь достаточно ответственная. И от оператора delete ожидается все-таки освобождение памяти. Если менеджер памяти четко знает как выделен блок, то почему тогда не выкинуть исключение? Наверное менеджера ничего кроме указателя на блок не интересует, тогда UB просто нелогичен...

В общем пошел флуд, размышления о вечном  smile 


Цитата(archimed7592 @  21.5.2007,  13:52 Найти цитируемый пост)
если взять компьютер васи пупкина, находящийся в зимбабве, то утечки не будет...

Сравнение неадекватное. Билдер является нормальным компилятором, со своими тараканами, но тут на вкус и на цвет... мне кажется компиляторов без недостатков не бывает. 
Я вообще и не собирался спорить - это был не спор, а попытка выяснить все-таки: как стандарт предписывает вести себя оператору delete. Конкретно Билдер ведет себя так. Если в стандарте написано UB - значит Билдер придерживается стандарта. Если написано, что должен освобождать блок - значит тоже придерживается.  smile 

PM MAIL ICQ   Вверх
archimed7592
Дата 21.5.2007, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(IS-5.3.5)
In the second alternative (delete array), the value of the operand of delete shall be the pointer value which resulted from a previous array new-expression. If not, the behavior is undefined. [Note: this means that the syntax of the delete-expression must match the type of the object allocated by new, not the syntax of the new-expression. ]
выяснили? smile
может больше не будем даже упоминать даже о возможности такого в билдере с тараканами?

Добавлено через 4 минуты и 15 секунд
эээ... хотя тут сказано, что нельзя делать new->delete[]
по поводу new[]->delete чуть выше:
Цитата(IS-5.3.5)
In the first alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object or a pointer to a sub-object (1.8) representing a base class of such an object (clause 10). If not, the behavior 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
PM Jabber   Вверх
Anikmar
Дата 21.5.2007, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(archimed7592 @  21.5.2007,  14:32 Найти цитируемый пост)
выяснили? 
может больше не будем даже упоминать даже о возможности такого в билдере с тараканами? 

Я вообще-то ни слова не говорил про второй вариант нотации. Т.е., что можно использовать delete[] к объекту выделенному просто new. Это и ежу понятно - какие деструкторы он вызовет? С этим то как раз все ясно.

Я говорил, что интересно бы узнать, как должен по-стандарту вести себя delete, примененный к объекту, выделенному new[]

По поводу тараканов: Вариант UB предусматривает любое поведение - так что Билдер по-любому ведет себя соответствующим стандарту образом. И почему собственно мы должны не упоминать о специфике поведения конкретного транслятора? Сейчас возникло обсуждение реализации конкретного участка стандарта, я пользуюсь билдером, что уж тут поделаешь...

Просто где-то я встречал описание delete как расширенный вариант вызова функции free. Так последняя вроде как вообще на вход void* получает...


PM MAIL ICQ   Вверх
archimed7592
Дата 21.5.2007, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(Anikmar @  21.5.2007,  14:44 Найти цитируемый пост)
Я говорил, что интересно бы узнать, как должен по-стандарту вести себя delete, примененный к объекту, выделенному 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
PM Jabber   Вверх
Anikmar
Дата 21.5.2007, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(archimed7592 @  21.5.2007,  14:32 Найти цитируемый пост)
Добавлено через 4 минуты и 15 секунд
эээ... хотя тут сказано, что нельзя делать new->delete[]
по поводу new[]->delete чуть выше:
Цитата(IS-5.3.5)
In the first alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object or a pointer to a sub-object (1.8) representing a base class of such an object (clause 10). If not, the behavior is undefined.

Вот именно - это меня и смутило.
Одномерный массив приводится по-умолчанию к указателю на объект, именно поэтому, вызов соответствует стандарту - т.е. вызывается деструктор только для первого объекта. А вот вопрос: освобождается ли блок памяти. Ведь формально, в стандарте написано, что данная нотация применима к адресу объекта. Иначе - UB. Если мы этому оператору передаем имя массива, то он приводится к указателю, чем формально разрешает использование delete. Последний честно вызывает деструктор к первому объекту и освобождает память. Вопрос: Правильно ли он ее освобождает?
PM MAIL ICQ   Вверх
archimed7592
Дата 21.5.2007, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(Anikmar @  21.5.2007,  14:44 Найти цитируемый пост)
По поводу тараканов: Вариант UB предусматривает любое поведение - так что Билдер по-любому ведет себя соответствующим стандарту образом. И почему собственно мы должны не упоминать о специфике поведения конкретного транслятора? Сейчас возникло обсуждение реализации конкретного участка стандарта, я пользуюсь билдером, что уж тут поделаешь...
имхо, такие заявления будут полезны в форуме, посвященном билдеру...
нет, возможно это мне одному режет глаз, когда говорят, что так делать "в принципе можно, если будешь сидеть на билдере, да ещё и такой-то версии, да ещё и такой-то сборки... и забудешь про возможность использования своего кода в других или более новых компиляторах..."
мы же здесь общие вопросы обсуждаем, а не билдер... ежу понятно, что в билдере какое-то да поведение на этот счёт предусмотренно... но блин, это не значит, что нужно использовать эти знания о тараканах билдера при программировании...

Добавлено через 14 минут и 40 секунд
Цитата
Одномерный массив приводится по-умолчанию к указателю на объект, именно поэтому, вызов соответствует стандарту - т.е. вызывается деструктор только для первого объекта. А вот вопрос: освобождается ли блок памяти. Ведь формально, в стандарте написано, что данная нотация применима к адресу объекта. Иначе - UB. Если мы этому оператору передаем имя массива, то он приводится к указателю, чем формально разрешает использование delete. Последний честно вызывает деструктор к первому объекту и освобождает память. Вопрос: Правильно ли он ее освобождает?

Цитата(IS-5.3.4 New)
A new-expression obtains storage for the object by calling an allocation function (3.7.3.1). If the newexpression terminates by throwing an exception, it may release storage by calling a deallocation function (3.7.3.2). If the allocated type is a non-array type, the allocation function’s name is operator new and the deallocation function’s name is operator delete. If the allocated type is an array type, the allocation function’s name is operator new[] and the deallocation function’s name is
operator delete[]

Цитата(IS-5.3.5 Delete)
The delete-expression will call a deallocation function (3.7.3.2).

Цитата(IS-3.7.3.2 Deallocation functions)
The value of the first argument supplied to one of the deallocation functions provided in the standard library may be a null pointer value; if so, the call to the deallocation function has no effect. Otherwise, the value supplied to operator delete(void*) in the standard library shall be one of the values returned by a previous invocation of either operator new(size_t) or operator new(size_t, const std::nothrow_t&) in the standard library, and the value supplied to operator delete[](void*) in the standard library shall be one of the values returned by a previous invocation of either operator new[](size_t) or operator new[](size_t, const std::nothrow_t&) in the standard library.

If the argument given to a deallocation function in the standard library is a pointer that is not the null pointer value (4.10), the deallocation function shall deallocate the storage referenced by the pointer, rendering invalid all pointers referring to any part of the deallocated storage. The effect of using an invalid pointer value (including passing it to a deallocation function) 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
PM Jabber   Вверх
archimed7592
Дата 21.5.2007, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 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
PM Jabber   Вверх
Anikmar
Дата 21.5.2007, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(archimed7592 @  21.5.2007,  14:54 Найти цитируемый пост)
имхо, такие заявления будут полезны в форуме, посвященном билдеру...
нет, возможно это мне одному режет глаз, когда говорят, что так делать "в принципе можно, если будешь сидеть на билдере, да ещё и такой-то версии, да ещё и такой-то сборки... и забудешь про возможность использования своего кода в других или более новых компиляторах..."
мы же здесь общие вопросы обсуждаем, а не билдер... ежу понятно, что в билдере какое-то да поведение на этот счёт предусмотренно... но блин, это не значит, что нужно использовать эти знания о тараканах билдера при программировании... 

Да причем здесь Билдер? Я его как пример привел, потому, что просто работаю сейчас на нем. Меня вовсе не это интересовало, а вариант утечки памяти.
Просто сразу в головоу примеры не приходят, но нутром чувствую, что возможны варианты смены формы этих операторов, по отношению именно к базовым типам. Одно дело, что так никто не делает и это режет глаза. Друго дело, что так делать категорически нельзя - так как вариант UB.
Я так никогда не делаю, и в своем первом посте именно так написал:
Цитата(Anikmar @  21.5.2007,  10:42 Найти цитируемый пост)
Тем не менее так делать не надо, разные компиляторы возможно ведут себя по-разному.

Вы почему-то считаете, что я с вами спорю. Как раз наоборот, этот вопрос мне прсто интересен так как я его не очень хорошо представляю. Не отделбную же тему заводить - просто к случаю возник, вот я и поинтересовался. Я всегда считал, что форма [] отличается от обычной вызовом деструкторов. Но так как к базовым типам деструкторы не применяются, то и возник этот этот вопрос. 
Интересно, а что делает delete по отношению к указателю void*? Ведь по логике - 100% UB, а компилер даже ворнинг не дает на эту конструкцию... Странно.

Добавлено через 3 минуты и 21 секунду
А господин Страуструп добавляет путаницы (2-е издание):
Цитата

Не используйте malloc(), эту операцию лучше реализует new ($$3.2.6).  


PM MAIL ICQ   Вверх
archimed7592
Дата 21.5.2007, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(Anikmar @  21.5.2007,  15:13 Найти цитируемый пост)
Одно дело, что так никто не делает и это режет глаза. Друго дело, что так делать категорически нельзя - так как вариант UB.
ок, твой интерес удовлетворён моими цитатами из стандарта? могу перевести на русский основную мысль, если нужно...

Цитата(Anikmar @  21.5.2007,  15:13 Найти цитируемый пост)
Я всегда считал, что форма [] отличается от обычной вызовом деструкторов.
возможно, возможно, даже в turbo-c++ так и есть... возможно и в более современных компиляторах... но, возможно, что ещё как отличается...

Цитата(Anikmar @  21.5.2007,  15:13 Найти цитируемый пост)
Интересно, а что делает delete по отношению к указателю void*? Ведь по логике - 100% UB, а компилер даже ворнинг не дает на эту конструкцию... Странно.
во-первых, компилятор не обзан приводить ворнинги на каждое UB... во-вторых, на некоторые извращённые случаи 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
PM Jabber   Вверх
Daevaorn
Дата 21.5.2007, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(archimed7592 @  21.5.2007,  15:54 Найти цитируемый пост)
нет, возможно это мне одному режет глаз, когда говорят, что так делать "в принципе можно, если будешь сидеть на билдере, да ещё и такой-то версии, да ещё и такой-то сборки... и забудешь про возможность использования своего кода в других или более новых компиляторах..."

нет. не тебе одному.
А вот Anikmar'а совсем не понимаю. Что-то совсем не то говорит. Уже и стандарт ему привели, пора и успокоиться вроде какsmile 
PM MAIL WWW   Вверх
Anikmar
Дата 21.5.2007, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(Daevaorn @  21.5.2007,  15:27 Найти цитируемый пост)
А вот Anikmar'а совсем не понимаю. Что-то совсем не то говорит. Уже и стандарт ему привели, пора и успокоиться вроде как  

Интересно, что это я такое не то говорю? Вообще-то я спрашиваю и ни с кем не спорю. А повышаю немного уровень своих знаний дабы избежать глупых ошибок.
Я сам попросил перевести мне стандарт и указал пункты стандарта - так как мне маленько непонятен именно этот аспект. Во 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 непонятно почему должен возникнуть...
PM MAIL ICQ   Вверх
Daevaorn
Дата 21.5.2007, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(Anikmar @  21.5.2007,  16:49 Найти цитируемый пост)
Описаны они так:        void* operator new(size_t);        void operator delete(void*);

да. и их так же можно и использовать как malloc
Код

void* buf = operator new( 10 );
//...
operator delete( buf );

Цитата(Anikmar @  21.5.2007,  16:49 Найти цитируемый пост)
А вот если нет - вариант UB меня сильно смущает - если оператор delete[] работает правильно, а оператор delete нет, то как они отличаются внутри?

на моём микроконтролере память под массивы расположенна в другом оптимизированном для данной задачи месте. и мой менеджер памяти не проверяет тот ли блок ему подсунули, а для увеличения скорости просто освобождает её. если подсунуть не тот блок, то всё рушится.
Цитата(Anikmar @  21.5.2007,  16:49 Найти цитируемый пост)
CodeGuard включен 

твой Builder уже надоелsmile
Цитата(Anikmar @  21.5.2007,  16:49 Найти цитируемый пост)
Просто мне интересно: как это устроено! 

посмотри исходники своей стандартной библиотеки
Цитата(Anikmar @  21.5.2007,  16:49 Найти цитируемый пост)
 И это говорит Страуструп (вроде как я к его мнению прислушиваюсь).

к счатью он не стандарт

Это сообщение отредактировал(а) Daevaorn - 21.5.2007, 16:18
PM MAIL WWW   Вверх
archimed7592
Дата 21.5.2007, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(Daevaorn @  21.5.2007,  15:58 Найти цитируемый пост)
да. и их так же можно и использовать как malloc
угу... только #include <new> не забывать smile


--------------------
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
PM Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1218 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.