Re[3]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 30.11.09 19:38
Оценка: 8 (3) +2
Здравствуйте, alexander_st, Вы писали:

_>чтобы испортить указатели ф-я не должна стрелять в стек, она должна всего лишь вызвать для них delete и лечится это передачей константных указателей


Не лечится Удалять указатели на константы можно.
Если уж позволено рефакторить программу, то нужно заменить сигнатуру g на что-нибудь такое
void g(std::vector<char>& a, std::vector<char>& b); // n не нужно, т.к. размеры переданы в составе объектов

// либо
void g(boost::shared_array<char> a, boost::shared_array<char> b, size_t n)

void f(size_t n)
{
  boost::shared_array<char> a(new char[n]), b(new char[n]);
  g(a,b,n); // g может передать права собственности куда-то на сторону
            // тогда по выходу из f() массивы останутся жить, как и задумано!
}


_>чем в данном контексте использование std::vector лучше, чем непосредственный указатели?

К>>А вот метнуть исключение функция g() может запросто.
_>но в вашем коде так же нет защиты от метания исключений

Вот как раз этим-то и лучше, что защита есть.
Вылет исключения — это частный случай выхода из блока. При этом разматывается стек, вызываются деструкторы.
А то, что я никак не перехватываю и не обрабатываю исключения (ни std::bad_alloc, ни, тем более, неизвестно что из недр g()) — ну так, от меня это и не требовалось... Тот, кто сможет, этажом выше, то и обработает. А я лишь обеспечу непротиворечивость своего участка системы.
Перекуём баги на фичи!
Re[3]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 30.11.09 19:45
Оценка: +1
Здравствуйте, Vamp, Вы писали:

К>>А вот метнуть исключение функция g() может запросто.

V>А вот это маловероятно. Сигнатура функции предполагает, что она написана не на С++, а на С. А значит, скорее всего, никаких исключений она бросить не может.

Да щас!
Во-первых, сишная функция может вызвать сиплюсплюсную, и исключение полетит оттуда. И прекрасно перелетит через сишный слой.
Во-вторых, мало ли у кого какие олдскульные замашки остались.
В-третьих, сишная функция может метнуть структурное исключение (windows-specific). Аварийный размотчик стека готов и к таким испытаниям.

Вот если бы функция была объявлена void g(char*,char*,size_t)throw() — это другое дело... Но она же не объявлена.

V>И по большому счету, я вижу реальную проблему только в printf.


Проблема в том, что задание провалено. То ли пастор Шлаг замечтался, вдыхая воздух свободы, то ли папаша Мюллер был чересчур внимателен... В пересказе топикстартера не хватает подробностей, чтобы понять, что там на самом деле.
Перекуём баги на фичи!
Re[2]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 30.11.09 19:53
Оценка: +2
Здравствуйте, Kernan, Вы писали:

Зачем усложнять, говоришь? Согласен. Зачем усложняешь?
K>
K>void g( const char *, const char *, size_t ); // константности в исходной задаче не было...
K>void f( size_t n )
K>{
K> сhar *a = NULL;
K> char *b = NULL;
  
K> if (n <= 0) // усложнение номер раз: size_t беззнаковое
K>     return; // неоправданность: а может, g() должен выполняться и при нулевой длине?
K> try
K> {
K>    a = new char[n]; // для справки: new char[0] возвращает ненулевой указатель на пустой массив.
K>    b = new char[n];
K>    g( a, b, n );
K> }
K> catch (...)
K> {
K>    if (a) delete [] a; // усложнение номер два: delete[] и для нулевого указателя работает корректно
K>    if (b) delete [] b; // номер два-бис
      // забыл сделать throw; - сожрал исключение (может быть, оно кому-то пригодилось бы выше?)
K> }
K> if (a) delete [] a; // бабах! повторное удаление (если первое было в catch(...))
K> if (b) delete [] b; // бабах-бис
K>}
K>

K>какие авто_птр?? какой буст??? Зачем усложнять жизнь в тривиальном куске кода? KISS!
auto_ptr и boost — это как раз и есть воплощение KISS, в отличие от мосвелосипедстроймонтажа.


K>Не смущает, что нумерация массива начинается с 0, и в argc[0] == 'имя исполняемого файла'?

K>Т.е. argc всегда > 0
Не смущает, что условие — if(argc>1), т.е. if(argc>=2), т.е. argv[1] валиден?
Перекуём баги на фичи!
Re[4]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 30.11.09 19:55
Оценка: 3 (1)
Здравствуйте, igna, Вы писали:

I>
R>>> std::auto_ptr<char> a (new char[n]);
R>>> std::auto_ptr<char> b (new char[n]);
I>


S>>Тут UB.

I>Почему?

Потому что delete new[]. Непарная операция.
Хотя для POD-типов и обычных менеджеров памяти (не изысканных-навороченных-специфических) это сведётся к free(malloc()).
Перекуём баги на фичи!
Re[4]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 19:56
Оценка: -2
К>Да щас!
К>Во-первых, сишная функция может вызвать сиплюсплюсную, и исключение полетит оттуда. И прекрасно перелетит через сишный слой.
Это правда. Об этом не подумал.

К>Во-вторых, мало ли у кого какие олдскульные замашки остались.

Ну нет. Уж если человек не пользуется векторами, то исключений он, скорее всего, тоже не признает.

К>В-третьих, сишная функция может метнуть структурное исключение (windows-specific). Аварийный размотчик стека готов и к таким испытаниям.

А может, это под Unix все работает? И там не SEH, а SIGBUS?

К>Проблема в том, что задание провалено.

Я не думаю, что это проблема . Работать в организации, предлагающей такие задания как дистанционное — верный путь в никуда. Очевидно, что задание предполагает тщательное обсуждение с кандидатом после ЛЮБОГО его ответа.
Да здравствует мыло душистое и веревка пушистая.
Re[5]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 30.11.09 19:57
Оценка:
Здравствуйте, alexander_st, Вы писали:

V>>Вообще-то, никто не мешает вызвать delete для константных указателей.

_>Уп-с ... правда?
_>давно последний раз пробовали?

Да вот только что: http://codepad.org/9DrfRKDV
Перекуём баги на фичи!
Re[5]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 30.11.09 20:07
Оценка:
Здравствуйте, Vamp, Вы писали:

К>>Во-вторых, мало ли у кого какие олдскульные замашки остались.

V>Ну нет. Уж если человек не пользуется векторами, то исключений он, скорее всего, тоже не признает.

Незнание законов не освобождает от ответственности. Раз есть new, значит, есть и std::bad_alloc.
Вот если на уровне main() забыли написать try-catch, ловящий все долетающие до этого уровня исключения, то внезапный бросок приведёт к terminate(), и тут, конечно, уже пофиг на какую-либо стековую гигиену.

К>>В-третьих, сишная функция может метнуть структурное исключение (windows-specific). Аварийный размотчик стека готов и к таким испытаниям.

V>А может, это под Unix все работает? И там не SEH, а SIGBUS?

А кстати, как в юниксе принято раскручивать стек после сигналов?
В виндах всё несложно: каждая функция, собирающаяся раскручивать, просто на входе в блок регистрирует обработчик исключения, на выходе дерегистрирует. И задача этого обработчика — вызвать деструкторы и отпустить исключение дальше, к следующему обработчику в цепочке. Компилятор берёт на себя задачу написать такой пролог-эпилог. В никсах компилятор не столь добр к пользователю, ну так это уже его личная лень

К>>Проблема в том, что задание провалено.

V>Я не думаю, что это проблема . Работать в организации, предлагающей такие задания как дистанционное — верный путь в никуда. Очевидно, что задание предполагает тщательное обсуждение с кандидатом после ЛЮБОГО его ответа.

Не буду заниматься инсинуациями, не зная подробностей
Перекуём баги на фичи!
Re[6]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 20:20
Оценка:
К>Незнание законов не освобождает от ответственности. Раз есть new, значит, есть и std::bad_alloc.
Где? В вызывающей функции он есть. Но я вообще-то не считаю, что bad_alloc надо перехватывать, за исключением редких стратегий типа — попросим 10 гиг, не получилось — тогда 5, опять не получилось, тогда 2 Кб. Как правило, программа просит столько памяти, сколько ей надо для работы, и ничего осмысленного после bad_alloc сделать не сможет. Более того, в ситуации тотальной нехватки вполне возможно, что даже диагностические сообщения вывести не удастся, так что пусть уж честно рушится. По крайней мере, в тех же Unix будет вполне читабельная корка.

К>А кстати, как в юниксе принято раскручивать стек после сигналов?

Никак. С другой стороны, сигналы как правило посылаются только в том случае, когда сделать уже реально ничего нельзя. Ну как ты будешь раскручивать стек, если у тебя стек порушился к чертям?

К>Не буду заниматься инсинуациями, не зная подробностей

Это же самое интересное!
Да здравствует мыло душистое и веревка пушистая.
Re[3]: Тестовое задание C++ win
От: Smal Россия  
Дата: 30.11.09 20:44
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Kernan, Вы писали:


I>
K>> catch (...)
K>> {
K>>    if (a) delete [] a;
K>>    if (b) delete [] b;
K>> }
K>> if (a) delete [] a;
K>> if (b) delete [] b;
I>


I>Здесь дублируются оба delete, такой код трудно сопровождать.


И if-ы лишние. delete отлично удаляет нулевой указатель.
С уважением, Александр
Re[2]: Тестовое задание C++ win
От: wander  
Дата: 30.11.09 20:49
Оценка:
Здравствуйте, Bell, Вы писали:

B>Не понятно, что означает фраза

B>

B>g может "испортить" указатели

B>

Там может быть вызван delete[], там может быть перевыделена память, например другим способом. соответственно delete[] вызванный после
Re[3]: Тестовое задание C++ win
От: landerhigh Пират  
Дата: 30.11.09 22:37
Оценка: 4 (2)
Здравствуйте, amberovsky, Вы писали:

A>Это удалённый пре-тест для отсева.

Для отсева кого?
www.blinnov.com
Re[4]: Тестовое задание C++ win
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 01.12.09 08:42
Оценка: -1
Здравствуйте, Smal, Вы писали:

S>Здравствуйте, igna, Вы писали:


I>>Здравствуйте, Kernan, Вы писали:


I>>
K>>> catch (...)
K>>> {
K>>>    if (a) delete [] a;
K>>>    if (b) delete [] b;
K>>> }
K>>> if (a) delete [] a;
K>>> if (b) delete [] b;
I>>


I>>Здесь дублируются оба delete, такой код трудно сопровождать.


S>И if-ы лишние. delete отлично удаляет нулевой указатель.

не все компиляторы одинаково полезны.
Sic luceat lux!
Re[3]: Тестовое задание C++ win
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 01.12.09 08:42
Оценка:
Здравствуйте, Vamp, Вы писали:

K>>какие авто_птр?? какой буст??? Зачем усложнять жизнь в тривиальном куске кода? KISS!

V>А ведь ты не понял принцип КИСС.
Просвяти меня.
Sic luceat lux!
Re[3]: Тестовое задание C++ win
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 01.12.09 08:45
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Kernan, Вы писали:


I>
K>> catch (...)
K>> {
K>>    if (a) delete [] a;
K>>    if (b) delete [] b;
K>> }
K>> if (a) delete [] a;
K>> if (b) delete [] b;
I>


I>Здесь дублируются оба delete, такой код трудно сопровождать.

Соглашусь. В catch delete лучше убрать.
Sic luceat lux!
Re[3]: Тестовое задание C++ win
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 01.12.09 08:47
Оценка: -3
Здравствуйте, Кодт, Вы писали:

К>auto_ptr и boost — это как раз и есть воплощение KISS, в отличие от мосвелосипедстроймонтажа.

Каки бусты/stl в 3-х строчках кода, а? Надеюсь, ты не из тех кто начинает использовать стратегии, где достаточно православного switch?
Sic luceat lux!
Re: Тестовое задание C++ win
От: Alexey_VL  
Дата: 01.12.09 09:01
Оценка: -1
Здравствуйте, amberovsky,

Теоретически, в g() могли переставить указатели на что-нибудь другое, и не удалить то, на что они указывали. Лечится с помощью void g( char * const, char * const, size_t ); Хотя в реальных проектах пока ни разу не встречал такой защиты.
Мафиозная диктатура это нестабильность. Если не мафиозная диктатура, то Конституция и демократия.
Re[2]: Тестовое задание C++ win
От: 24  
Дата: 01.12.09 09:27
Оценка: 1 (1)
A_V>Теоретически, в g() могли переставить указатели на что-нибудь другое, и не удалить то, на что они указывали.
Не могли там такого сделать. Внутри этой функции она бы переставила свои локальные копии указателей, а не исходные. Чтоб была возможность переставить исходные указатели, описание функции должно быть таким:
void g( char * &, char * &, size_t );
Re[3]: Тестовое задание C++ win
От: Alexey_VL  
Дата: 01.12.09 09:35
Оценка:
Здравствуйте, 24, Вы писали:

Согласен, был неправ
Мафиозная диктатура это нестабильность. Если не мафиозная диктатура, то Конституция и демократия.
Re[5]: Тестовое задание C++ win
От: andrey.desman  
Дата: 01.12.09 09:52
Оценка:
Здравствуйте, Kernan, Вы писали:

S>>И if-ы лишние. delete отлично удаляет нулевой указатель.

K>не все компиляторы одинаково полезны.

Компилятор здесь ни при чем. delete, равно как и free нулевого указателя — это законная операция, так что смысла в проверках нет, если только тебе не платят за килограммы кода

Но разу уж мы пишем в c-стиле, то надо идти до конца
void g( const char *, const char *, size_t );
void f( size_t n )
{
 сhar *a = malloc(n),
      *b = malloc(n);

 if (a && b) g( a, b, n );

 free(a);
 free(b);
}
Re[4]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 01.12.09 10:35
Оценка: 1 (1) +9
Здравствуйте, Kernan, Вы писали:

К>>auto_ptr и boost — это как раз и есть воплощение KISS, в отличие от мосвелосипедстроймонтажа.

K>Каки бусты/stl в 3-х строчках кода, а? Надеюсь, ты не из тех кто начинает использовать стратегии, где достаточно православного switch?

Привет участникам синтаксического оверхеда(tm)!
                                    #include <vector>

void f( size_t n )
{
 сhar *a = NULL;                    std::vector<char> a(max(n,1));
 char *b = NULL;                    std::vector<char> b(max(n,1));
  
 if (n <= 0)                        //
     return;                        //
 try                                //
 {                                  //
    a = new char[n];                //
    b = new char[n];                //
    g( a, b, n );                   g(&a[0], &b[0], n);
 }                                  //
 catch (...)                        //
 {                                  //
    if (a) delete [] a;             //
    if (b) delete [] b;             //
 }                                  //
 if (a) delete [] a;                //
 if (b) delete [] b;                //
}

Ну и у кого из нас три строчки?
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.