Re: Тестовое задание C++ win
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 30.11.09 16:25
Оценка: 1 (1) +1 -12 :))) :))) :))) :)))
Здравствуйте, amberovsky, Вы писали:

A>Здравствуйте.

A>При попытке устроится в одну фирму прислали "удалённое" тестовое задание.



A>
A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}
A>


void g( const char *, const char *, size_t );
void f( size_t n )
{
 сhar *a = NULL;
 char *b = NULL;
  
 if (n <= 0)
     return;
 try
 {
    a = new char[n];
    b = new char[n];
    g( a, b, n );
 }
 catch (...)
 {
    if (a) delete [] a;
    if (b) delete [] b;
 }
 if (a) delete [] a;
 if (b) delete [] b;
}

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

A>
A>2.
A>int main(int argc, char* argv[])
A>{
A> if( argc > 1 )
A>  printf( argv[1] );
A> return 0;
A>}
A>

Не смущает, что нумерация массива начинается с 0, и в argc[0] == 'имя исполняемого файла'?
Т.е. argc всегда > 0
Sic luceat lux!
Re: Тестовое задание C++ win
От: landerhigh Пират  
Дата: 30.11.09 12:00
Оценка: 3 (3) +10 :))) :)))
Здравствуйте, amberovsky, Вы писали:

A>
A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>


Главная проблема — это не тест по C++
www.blinnov.com
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>>
Перекуём баги на фичи!
Re[2]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 14:48
Оценка: -3 :))) :)))
R>Если вылетит исключение при выделении памяти под b, то память для a не будет освобождена -> утечка память.
Ну какая утечка? Если вылетит исключение в приведенном фрагменте, программа просто завершится и всю память почистит ОС.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: Тестовое задание C++ win
От: Smal Россия  
Дата: 30.11.09 11:52
Оценка: 4 (2) +6
Здравствуйте, remark, Вы писали:

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


A>>
A>>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>>1.
A>>void g( char *, char *, size_t );
A>>void f( size_t n )
A>>{
A>> char *a = new char[n];
A>> char *b = new char[n];
A>> g( a, b, n );
A>> delete [] b;
A>> delete [] a;
A>>}
A>>


A>>Я ответил так:

A>>1. new может не сработать, нужно добавить, например, try/catch. Кроме того, g может "испортить" указатели (как тут просто решить я не знаю)

R>Если вылетит исключение при выделении памяти под b, то память для a не будет освобождена -> утечка память.

R>Ну и плюс в целом ручное управление памятью чревато проблемами при поддержке, поэтому кошерно будет:

R>
R>void f( size_t n )
R>{
R> std::auto_ptr<char> a (new char[n]);
R> std::auto_ptr<char> b (new char[n]);
R> g( a.get(), b.get(), n );
R>}
R>


Тут UB.

R>Если доступен scoped_ptr<>, то лучше использовать его.


Ну, тогда уж
void f( size_t n )
{
 std::vector<char> a (n);
 std::vector<char> b (n);
 g( &a[0], &b[0], n );
}


или

void f( size_t n )
{
 boost::scoped_array<char> a (new char[n]);
 boost::scoped_array<char> b (new char[n]);
 g( a.get(), b.get(), n );
}
С уважением, Александр
Re: Тестовое задание C++ win
От: любой  
Дата: 30.11.09 13:46
Оценка: 17 (4) +2
Здравствуйте, amberovsky, Вы писали:

A>[ccode]

A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}

Тут по существу уже сказали. А меня в таком коде всегда прикалывает, почему два блока нельзя за раз выделить:

char *a = new char[n*2];
char *b = a + n;
g( a, b, n );
delete [] a;
художников никогда не обижал
Re[5]: Тестовое задание C++ win
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 01.12.09 11:43
Оценка: -5 :)
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, 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;                //
К>}
К>

К>Ну и у кого из нас три строчки?
вот только вопрос есть, тебе на вход приходит 0, а на вход функции g ты передёшь 1. Подмена понятий, однако. Хотя код неплох, есть чему поучится
Sic luceat lux!
Re: Тестовое задание C++ win
От: Кодт Россия  
Дата: 30.11.09 14:38
Оценка: 19 (5)
Здравствуйте, amberovsky, Вы писали:

A>1. new может не сработать, нужно добавить, например, try/catch.

Лучше не try-catch (это слишком громоздко), а RAII — любой умный указатель или контейнер.

A> Кроме того, g может "испортить" указатели (как тут просто решить я не знаю)

Паранойя. Чтобы испортить указатели, функция должна расстрелять стек. А это никакими средствами не лечится.
А вот метнуть исключение функция g() может запросто.

Решение
void f(size_t n)
{
    if(n!=0)
    {
        std::vector<char> a(n), b(n);
        g(&a.front(), &b.front(), n);
    }
    else // если мы ничего не знаем про логику g(), попробуем максимально близко воспроизвести ситуацию
    {
        char a,b;
        g(&a,&b,0); // передаём два уникальных ненулевых адреса! ибо new char[0] != NULL
        
        // хотя, возможно, было бы достаточно
        g(NULL,NULL,0);
    }
    // или, в обобщённом виде
    std::vector<char> a(max(n,1)), b(max(n,1)); // гарантируем непустоту и уникальность
    g(&a.front(), &b.front(), n);
}


A>2. В аргументе командной строки может встретиться символ % или \, что будет расценено printf как специальный символ.

A>Если следующие символы совпадут с какой-либо спецификацией формата (для % или \), то в данном случае для % — UB, для \ — произойдёт подстановка.

Про бэкслеш — фантазия. Для принтфа спецсимволом является только %.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
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[2]: Тестовое задание C++ win
От: sergey_cheban  
Дата: 04.05.10 19:08
Оценка: 1 (1) +1 :)))
Здравствуйте, Константин.

KC>В общем, побывал я в DrWeb на собеседовании и даю правильный с их точки зрения ответ:

KC>По первому заданию:
Я рад, что обсуждение недостатков Вашего первоначального ответа пошло Вам на пользу. И всё же:
1. Хочу предостеречь от использования &a[0] без проверки на наличие в векторе хоть каких-то данных. Если мы не предупредили Вас об этой проблеме на собеседовании, это не значит, что её не существует.
2. Вся строчка "func f_drWeb said:" — это Ваши личные фантазии, к которым компания DrWeb не имеет ни малейшего отношения. Пусть они остаются на Вашей совести.

KC>По второму заданию:

Ваши упражнения с локалью пригодны только для одного случая: когда консольная программа вызывается с русскими аргументами в кодировке ANSI. Для случая "консольная программа вызывается из консоли" установка локали создаёт проблемы, а не решает их. На собеседовании Ваш ответ на этот вопрос вообще не обсуждался, и поэтому Ваши утверждения о причастности компании DrWeb к этому коду я решительно отвергаю.

KC>Кроме того, можете скачать http://piterludi.com/fordeveloponbox/stlfuns.zip

KC>В этом проекте (VC++ 2008) я продемонстрировал также поведение виртуальных функций, вызываемых из конструкторов и деструкторов — вопрос,
KC>который почему-то нередко возникает на собеседованиях. Также немного побаловался с промышленным дизайном для этой же задачи.
Вот этот фрагмент особенно порадовал:
void GFuncCaller_NOSTL::clearBuff()
{
        if(!BufferA) delete[] BufferA;// Это не защита. Если BufferA==NULL, проблем с deleteA все равно нет
        BufferA = NULL;                // просто незачем вызывать delete

        if(!BufferB) delete[] BufferB;
        BufferB = NULL;
        
        gBufferSize = 0;
};

У Вас действительно есть свой стиль написания кода. Вы только с названием стиля ошиблись: это не Industrial, а Trash.

KC>Хотя по ходу собеседования я и сделал вывод, что промышленный дизайн и общепринятые подходы они считают

KC>ненужным усложнением и ретроградством.
KC>Возможно, я ошибаюсь: все-таки собеседование проходило в стиле "опусти кандидата",
KC>а при таком стиле язвительно критикуется любое высказывание.
У нас во время собеседования действительно возникли разногласия в том, какие подходы считать общепринятыми. Но не более того.
Что касается стиля "опусти кандидата" — мы честно высказывали своё мнение о Ваших высказываниях и честно давали Вам возможность отстоять свою позицию по тем вопросам, по которым мы были с Вами не согласны.
А вот, например, по второму вопросу из письменного задания мы Вас не "опускали", и вот Вы уже рассказываете, что это и есть правильный, по нашему мнению, вариант.

KC>Вероятно, предполагается, что осознавший свое ничтожество и полностью дезориентированный кандидат

KC>преисполнится безумной радости, если ему все-таки сделают предложение поработать в такой новаторской фирме.
Пожалуйста, воздержитесь от обобщений. К нам и нормальные кандидаты приходят.

KC>Просто держите в голове, что "опустить" можно любого: конкретно моих "экзаменаторов" можно было бы легко "опустить" как минимум

KC>по знаниям паттернов проектирования (особенно сoncurrency) и подходам к разработке сложных систем.
Вы говорите это после того, как сами на собеседовании продемонстрировали незнание http://en.wikipedia.org/wiki/Reactor_pattern? И Вам не стыдно?

KC>Никто не может знать всего.

Этого мы от кандидатов и не требуем.

KC>Если будете у них на собеседовании — в момент, когда от вас потребуют что-либо написать, постарайтесь не отвлекаться

KC>на вопросы "экзаменаторов", "заторапливание" и попытки вывести вас из себя. Иначе наделаете таких ляпов, что самому потом будет стыдно.
...И постарайтесь не тратить по двадцать минут на вопросы типа "Эту задачу можно решить всего тремя строчками кода, а не тридцатью, как Вы предложили. Вы можете написать эти три строчки?".
Re: Тестовое задание C++ win
От: remark Россия http://www.1024cores.net/
Дата: 30.11.09 11:46
Оценка: +1 -4
Здравствуйте, amberovsky, Вы писали:

A>
A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}
A>


A>Я ответил так:

A>1. new может не сработать, нужно добавить, например, try/catch. Кроме того, g может "испортить" указатели (как тут просто решить я не знаю)

Если вылетит исключение при выделении памяти под b, то память для a не будет освобождена -> утечка память.
Ну и плюс в целом ручное управление памятью чревато проблемами при поддержке, поэтому кошерно будет:

void f( size_t n )
{
 std::auto_ptr<char> a (new char[n]);
 std::auto_ptr<char> b (new char[n]);
 g( a.get(), b.get(), n );
}


Если доступен scoped_ptr<>, то лучше использовать его.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Тестовое задание C++ win
От: alexander_st Россия  
Дата: 30.11.09 18:38
Оценка: -4 :)
Здравствуйте, Vamp, Вы писали:

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

Уп-с ... правда?
давно последний раз пробовали?
Re[5]: Тестовое задание C++ win
От: KoriBRand  
Дата: 26.12.09 13:17
Оценка: -4 :)
Здравствуйте, SergeyT., Вы писали:

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


S>>>Ну, тогда уж

S>>>
S>>>void f( size_t n )
S>>>{
S>>> std::vector<char> a (n);
S>>> std::vector<char> b (n);
S>>> g( &a[0], &b[0], n );
S>>>}
S>>>


ST>Это не очень красивая, но совершенно стандартная идиома.

ST>Скотт Мейерс, Эффективное использование STL, Item 16

Ну нахрен такие идиомы. Добавишь ты в вектор новый элемент, сделает он реаллокацию внутреннего буфера, и указатель, который передавался в doSomething станет невалидным. А функция могла его где-нибудь сохранить. Конечно, как правило такой сценарий или не возникает или ничем не грозит, но один раз из ста, когда грабли срабатывают, бывает достаточно неприятным.
offtop
Re[2]: Тестовое задание C++ win
От: alexander_st Россия  
Дата: 30.11.09 14:50
Оценка: -3 :)
Здравствуйте, Кодт, Вы писали:

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


A>>1. new может не сработать, нужно добавить, например, try/catch.

К>Лучше не try-catch (это слишком громоздко), а RAII — любой умный указатель или контейнер.
К>Паранойя. Чтобы испортить указатели, функция должна расстрелять стек. А это никакими средствами не лечится.
чтобы испортить указатели ф-я не должна стрелять в стек, она должна всего лишь вызвать для них delete и лечится это передачей константных указателей
то биш

g(const char*, const char*, size_t);


только не надо предположений что можно сделать всякие const_cast`ы и спецом все на свете по удалять, вот это уже действительно паранойя


К>Решение

К>
К>void f(size_t n)
К>{
К>    if(n!=0)
К>    {
К>        std::vector<char> a(n), b(n);
К>        g(&a.front(), &b.front(), n);
К>    }
К>    else // если мы ничего не знаем про логику g(), попробуем максимально близко воспроизвести ситуацию
К>    {
К>        char a,b;
К>        g(&a,&b,0); // передаём два уникальных ненулевых адреса! ибо new char[0] != NULL
        
К>        // хотя, возможно, было бы достаточно
К>        g(NULL,NULL,0);
К>    }
К>    // или, в обобщённом виде
К>    std::vector<char> a(max(n,1)), b(max(n,1)); // гарантируем непустоту и уникальность
К>    g(&a.front(), &b.front(), n);
К>}
К>


чем в данном контексте использование std::vector лучше, чем непосредственный указатели?
К>А вот метнуть исключение функция g() может запросто.
но в вашем коде так же нет защиты от метания исключений
Re[3]: Тестовое задание C++ win
От: sergey_cheban  
Дата: 07.05.10 14:56
Оценка: -4
Здравствуйте, KhConstantine, Вы писали:

>>> несколько десятков тысяч рублей чистого убытка

KC>Понятен стандартный уровень ваших зарплат.
С точностью до десятичного порядка — да, понятен и отсюда (т.е. это не сотни тысяч рублей в месяц и не тысячи за всё время испытательного срока). Но заглянув в описание наших вакансий, Вы получили бы куда более точную оценку.
Вы считаете, что нам следует терять на своих ошибках больше?

>>> до того, как он сможет претендовать на работу у нас

KC>Да, каждый сам устанавливает планку. И компании уровня "несколько десятков тысяч рублей"/брэнд из разряда "а разве они все еще существуют?" — тоже.
Не существует нас. И офис вам померещился, и собеседование. Сон это был. Переворачивайтесь на другой бок и спите дальше.

KC>В адаптированном виде описание применения транзакционного анализа нередко включается в ученики по управлению проектами, team building, etc

KC>В соответствии с этой терминологией: Практически все транзакции идут у Вас с позиции "родитель критикующий". Позиция известна, как наиболее конфликтная и наименее продуктивная. Человек, общающийся с этой позиции, в своем восприятии транслирует все ответные транзакции, к какому бы типу они ни принадлежали в действительности, исключительно в два типа: "Ребенок послушный->Родитель критикующий" и "ребенок непослушный-> родитель критикующий". Второй тип вызывает отторжение. Так, данный абзац оформлен в нейтральном стиле,
Я просто вынужден Вам сказать, что в Вас пропадает талантливый психолог. Попытайтесь трудоустроиться в психдиспансер. Там Вас обеспечат лицензией на занятие психиатрией, и после этого Вы сможете практиковать. А без лицензии — не надо.

PS. Шутки шутками, а вовремя пролечиться или оформить инвалидность — это лучше, чем помереть от безденежья.
Re[4]: Тестовое задание C++ win
От: Sergey Chadov Россия  
Дата: 30.11.09 17:25
Оценка: 8 (3)
Здравствуйте, igna, Вы писали:


I>
R>>>void f( size_t n )
R>>>{
R>>> std::auto_ptr<char> a (new char[n]);
R>>> std::auto_ptr<char> b (new char[n]);
R>>> g( a.get(), b.get(), n );
R>>>}
I>


S>>Тут UB.

I>Почему?

Потому что auto_ptr будет удалять память delete'ом без скобок.
--
Sergey Chadov

... << RSDN@Home 1.2.0 alpha rev. 685>>
Re[3]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 15:45
Оценка: 1 (1) +2
_>чтобы испортить указатели ф-я не должна стрелять в стек, она должна всего лишь вызвать для них delete и лечится это передачей константных указателей
Вообще-то, никто не мешает вызвать delete для константных указателей.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: Тестовое задание C++ win
От: srggal Украина  
Дата: 30.11.09 13:49
Оценка: +2 :)
Здравствуйте, любой, Вы писали:

Л>Тут по существу уже сказали. А меня в таком коде всегда прикалывает, почему два блока нельзя за раз выделить:


Л>char *a = new char[n*2];

Л>char *b = a + n;
Л>g( a, b, n );
Л>delete [] a;
несчастный_труженик_проекта>delete [] b;
Re[4]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 15:57
Оценка: -3
SC>Каким образом она это указывает?
Способом передачи параметров. Если бы она была написана на С++, она бы принимала два вектора.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 19:12
Оценка: +2 :)
K>какие авто_птр?? какой буст??? Зачем усложнять жизнь в тривиальном куске кода? KISS!
А ведь ты не понял принцип КИСС.
Да здравствует мыло душистое и веревка пушистая.
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[4]: Тестовое задание C++ win
От: igna Россия  
Дата: 01.12.09 11:14
Оценка: +3
Здравствуйте, Kernan, Вы писали:

K>Соглашусь. В catch delete лучше убрать.


catch, который ловит что попало и это "что попало" затем не перебрасывает, тоже лучше убрать.
Re[6]: Тестовое задание C++ win
От: igna Россия  
Дата: 01.12.09 14:15
Оценка: +3
Здравствуйте, Kernan, Вы писали:

K>вот только вопрос есть, тебе на вход приходит 0, а на вход функции g ты передёшь 1. Подмена понятий, однако.


Чья бы корова... В оригинальном примере функция g вызывается и в том случае, если "на вход приходит 0", а в твоем — нет.
Re[5]: Тестовое задание C++ win
От: Antikrot  
Дата: 07.05.10 19:35
Оценка: +3
Здравствуйте, sergey_cheban, Вы писали:

_>Надеюсь, Вы чувствуете границу между защитой чести и достоинства и самоутверждением. Я эту границу переходить не хочу.

Что не помешало Вам перейти границу "публично сраться с кандидатом после собеседования".
Зачем, спрашивается? Тем более, что, [имхо], рассказывать всем как вёл себя кандидат на собеседовании, — не принято.
Re[10]: Тестовое задание C++ win
От: midl  
Дата: 17.01.12 14:07
Оценка: +1 -1 :)
Здравствуйте, sergey_cheban, Вы писали:

M>>В общем, как я уже написал, на практике без дополнительных не видно смысла что-то с этим делать, тест, строго говоря, некорректный.

_>А представьте, каково нам. Мы решаем задачу, для которой математически строго доказана невозможность корректного решения: определяем, является ли файл вирусом. Ничего, как-то справляемся.
Втом то и дело, что "както". Т.е. коекак, с довольно фиговым результатом. Качество современных антивирусов оставляет желать лучшего.
Re[3]: Тестовое задание C++ win
От: Eugeny__ Украина  
Дата: 19.01.12 13:47
Оценка: +3
Здравствуйте, sergey_cheban, Вы писали:

_>Приветствую героев, дочитавших эту тему до шестнадцатой страницы.


Извините, что влезаю, но ваш тон сообщений и отношение к кандидатам очень сильно отталкивает. Чисто по-человечески, я бы даже как с коллегой не смог бы с вами работать, но, как я понимаю, вы еще и тимлид или что-то в таком роде — это еще хуже. Я, конечно, не знаю, что там у вас на рынке труда сиплюсплюсников, может их в свободной "продаже" как собак нерезанных(во что я очень плохо верю), но любой нормальный джавист(да и вообще любой из моих знакомых) при таком отношении к нему как к кандидату бежал бы как от огня(я уже не говорю про тестовое задание типа "хочу того, не скажу чего", но опять же, может для плюсов с их вагоном средств для прострела ноги это норма, я хз). Ну, разве что у вас зп в два раза выше рынка — некоторые бы повелись. Но я бы посоветовал вам все-таки спуститься с небес немного.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Re[3]: Тестовое задание C++ win
От: landerhigh Пират  
Дата: 30.11.09 22:37
Оценка: 4 (2)
Здравствуйте, amberovsky, Вы писали:

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

Для отсева кого?
www.blinnov.com
Re: Тестовое задание C++ win
От: SaZ  
Дата: 30.11.09 12:08
Оценка: 1 (1) +1
Здравствуйте, amberovsky, Вы писали:

A>Здравствуйте.

A>При попытке устроится в одну фирму прислали "удалённое" тестовое задание.

A>2. В аргументе командной строки может встретиться символ % или \, что будет расценено printf как специальный символ.


Про обратный слэш \ — не правда. Эти вещи обрабатываются компилятором. Если из командной строки передать обратный слэш, то он так и выведется, т.е. аргумент "\n" не приведёт к переводу командной строки, т.к. будет эквивалентен "\\n" с точки зрения компилятора.
Re: Тестовое задание C++ win
От: Uzumaki Naruto Ниоткуда  
Дата: 04.12.09 13:57
Оценка: 1 (1) +1
f(0);

Re: Тестовое задание C++ win
От: std.denis Россия  
Дата: 30.11.09 11:40
Оценка: +2
A>1.
Подозрительно как-то — создаются два массива, передаются в функцию без какой-либо инициализации, и после того как она отработает просто прибиваются, опять-таки без использования значений в массивах. Вопрос — зачем всё это?
Re[2]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 15:42
Оценка: -2
К>А вот метнуть исключение функция g() может запросто.
А вот это маловероятно. Сигнатура функции предполагает, что она написана не на С++, а на С. А значит, скорее всего, никаких исключений она бросить не может.
И по большому счету, я вижу реальную проблему только в 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
От: Vamp Россия  
Дата: 30.11.09 19:56
Оценка: -2
К>Да щас!
К>Во-первых, сишная функция может вызвать сиплюсплюсную, и исключение полетит оттуда. И прекрасно перелетит через сишный слой.
Это правда. Об этом не подумал.

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

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

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

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

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

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

К>>Возможно, что g() способно работать и с набором параметров g(NULL,NULL,0). Этого из начальных условий задачи мы не знаем. Поэтому я и предложил трюк с max(n,1).

К>>Тем более, что нагрузка на кучу для new char[0] и new char[1] (внутри vector) — почти одинаковая.
K>Получается, что ты предполагаешь, что функция g проверяет n >= 0, чего может и не быть. Более того, неизвестный код может длелать какие-то действия в случае (NULL, NULL, 0).

Я просто предложил наиболее консервативный рефакторинг.
А именно, обеспечил безопасность от исключений на ввереном мне участке, никак не затронув поведение остального кода (ни вызывающего, ни внутри g()).

Единственный упрёк в сторону векторов — то, что чуть-чуть изменяется рисунок стека и кучи. Это может сыграть в условиях стресс-тестирования.
boost::scoped_array — более предпочтительный вариант в этом плане.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[6]: Тестовое задание C++ win
От: alexander_st Россия  
Дата: 02.12.09 20:07
Оценка: :))
Здравствуйте, Кодт, Вы писали:

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


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

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

К>Да вот только что: http://codepad.org/9DrfRKDV

Из каких соображений тогда ну скажем ф-я std::string c_str() возвращает const char* а не просто char* ? может для того , что бы показать, что удалять этот буфер не надо?
Re[2]: Тестовое задание C++ win
От: minorlogic Украина  
Дата: 02.12.09 21:18
Оценка: +2
Здравствуйте, Kernan, Вы писали:


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


На всякий случай удалили 2 раза ? ))))))))
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re: Тестовое задание C++ win
От: McSeem2 США http://www.antigrain.com
Дата: 04.12.09 00:59
Оценка: +2
Здравствуйте, amberovsky, Вы писали:

A>
A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}
A>


Не вижу ни малейшей проблемы в этом примере. Точнее сказать так — все зависит от контекста применения. А контекста нету. Бывают, например, случаи, когда исключения вообще запрещены. И если new может венуть 0, а в g() это обрабатывается, то даный код полностью легален. Например, я вообще вынужден пользоваться longjmp, когда память кончается — А что поделаешь на Sony PS3 Cell? — исключения сразу раздувают код процентов на 30, а там — каждый килобайт на счету. Ну и гадость же этот cell оказался, сплошной рак головы. Ждем интел лараби с его кэш-когерентностью (если дождемся, конечно).
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re: Тестовое задание C++ win
От: runtime2  
Дата: 09.12.09 11:12
Оценка: :))
Здравствуйте, amberovsky, Вы писали:

A>2.

A>int main(int argc, char* argv[])
A>{
A> if( argc > 1 )
A> printf( argv[1] );
A> return 0;
A>}

A>[/ccode]


Этот вариант я бы так переписал:
const int valid_arguments_count = 1;

bool is_valid_arguments_count(int argc)
{
    return argc > valid_arguments_count;
}

int main(int argc, char* argv[])
{
    const int first_program_argument = 1;
    if( is_valid_arguments_count(argc) )
        std::cout << argv[first_program_argument] << std::endl;
    else
        std::cout << "Invalid arguments number. Valid: " << valid_arguments_count << std::endl;
    return 0;
}


Возможно, еще нужна поддержка unicode.
Re[3]: Тестовое задание C++ win
От: KhConstantine Россия  
Дата: 05.05.10 17:21
Оценка: -2
Здравствуйте, sergey_cheban, Вы писали:

_>Вот этот фрагмент особенно порадовал:

_>
_>void GFuncCaller_NOSTL::clearBuff()
_>{
_>        if(!BufferA) delete[] BufferA;// Это не защита. Если BufferA==NULL, проблем с deleteA все равно нет
_>        BufferA = NULL;                // просто незачем вызывать delete

_>        if(!BufferB) delete[] BufferB;
_>        BufferB = NULL;
        
_>        gBufferSize = 0;
_>};
_>

_>У Вас действительно есть свой стиль написания кода. Вы только с названием стиля ошиблись: это не Industrial, а Trash.


Блин... вызов delete как раз только при NULL... Ляп, однако. Конструкция "если указатель нулл, то сделать что-то" в пальцы въелась, однако...
Хотел напомнить, что удаление на указателе с NULL — НЕ вызывает exception, а перехват исключений можно делать не на атомарном уровне...

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

Господин гуру, а своим кодом нас, сирых и убогих недоучек, вы не могли бы порадовать? Понятное дело, баловством каким вашим собственным, а не кодом под копирайтом — да только не задачки мелкие, которые тяп-ляп да на скорую руку, а что-нибудь хотя бы отдаленно похожее на то, как вы крупные приложения дизайните... Показали бы класс. А то все критика да критика... Так критиковать чужой код — конечно, оно полегче будет, чем свой написать. Вы вообще хоть что-нибудь пишете?

А то мы, сирые да убогие, до сих пор почитаем всяких там Крэгов Ларманов да Мартинсов со всякими "бандами четырех" и т д — а ведь пишем-то всякий там трэш поганый... Ну а вы, такой новатор и знаток — ничего своего не показываете, критиковать вас не за что.
Разве что на пресловутом собеседовании, когда я вам объяснял архитектуру приложения, которое вычищал от ошибок на предыдущей работе — ляпнули,
что АСИНХРОННУЮ обработку АСИНХРОННЫХ запросов из МНОЖЕСТВЕННЫХ источников, причем с несовпадением порядка ответов с порядком запросов,
лучше делать в один поток... Дескать, процессор на сервак современный — и вперед... Причем объяснять, вам же, что вы можете иметь в виду, пришлось мне же, рисуя примитивную схему на бумаге, так как названную мной комбинацию шаблонов вы "не расслышали".

Кстати, в ваших словах про локаль — одна ошибка и, что для вас типично, масса неопределенности. Раз такие крутые — попробуйте выяснить сами.

Из вашего письма я сделал два вывода:
1. Я был абсолютно прав в своих оценках. Себя перечитайте... "трэш"...
2. Приход даже на такое собеседование — полезен. Для работодателя — вы добрались-таки хотя бы до википедии, чтобы взглянуть на выдумки ретроградов.
Еще ограничения и перечень проблем посмотрите — и вопрос "почему так не делают, хотя теоретически возможно" с асинхронной обработкой прояснится еще больше. К тому же вы отслеживаете сообщения на этой ветке — значит, что-то полезное надеетесь углядеть. Ну и по мелочам — к примеру, не задумывались, что конструктор исключений с о строкой в параметре — это "майкрософт специфик".

Для кандидата — не побывай я у вас, или веди вы себя прилично, не полез бы в интернет, чтобы поковыряться в вопросах, которые я посчитал откровенно дурными. Не нашел бы эту статью. И не увидел бы упоминания про "Эффективное использование STL", не прочитал, наконец, эту книгу и не добрался бы и до Александреску.
Re[3]: Тестовое задание C++ win
От: KhConstantine Россия  
Дата: 05.05.10 20:48
Оценка: -2
Здравствуйте, sergey_cheban, Вы писали:

_>Здравствуйте, Константин.


KC>>В общем, побывал я в DrWeb на собеседовании и даю правильный с их точки зрения ответ:

KC>>По первому заданию:
_>Я рад, что обсуждение недостатков Вашего первоначального ответа пошло Вам на пользу. И всё же:
_>1. Хочу предостеречь от использования &a[0] без проверки на наличие в векторе хоть каких-то данных. Если мы не предупредили Вас об этой проблеме на собеседовании, это не значит, что её не существует.

Этот пункт вашей любезной критики, о глубокоуважаемый эксперт, тоже заслуживает незначительных сомнений со стороны недостойного меня.
Позвольте полюбопытствовать: а в "докторе вебе" принято КАЖДЫЙ подобный вызов просто на всякий случай заворачивать в контроль передаваемых параметров? Даже несмотря на то, что обязанность вызывающей стороны — предоставить корректные параметры вызываемой функции? А потом, при изменении потребностей вызываемой функции в минимальном размере буфера, делать изменения по всему тексту? Понимаю, что древний принцип распределения полномочий (его вариант в ООД зовется "Information Expert") уже признан ретроградным, и не с моим скудоумием судить о передовых подходах, но все же: функция g обязана знать свои минимальные потребности и сама проверять входные параметры. Для этого ей n и передается. Если же ей передано n, а размещено меньше, так как программ без ошибок не бывает вообще... Я так понимаю, что процессы многоуровневого тестирования тоже устарели и по вашим расчетам все-таки гораздо дешевле встраивать проверки вообще везде, где только можно. И, кстати, код, который вы забыли процитировать, переоценив желание читателей скачивать файлы и разбираться в них:



void g(char* a, char* b, size_t n )
{
    // Функция на C.
    // Разместить что-нибудь в буферы для использования 
    // вызывающей функцией - традиционный способ 
    // Для контроля над правильностью размещения 
    // используется n. В данном случае - строка либо образается(но 0 не ставится),
    // либо дополняется нулями 
    if(!a || !b || !n)
        return; // на самом деле нормально написанная функция на C должна возвращать 
                // именованую константу, 
    
    strncpy(a, "one two three",n);
    a[n-1]='\0'; //
    
    strncpy(b, "three two one",n);
    b[n-1]='\0'; //
    
     // сделать что-нибудь еще
    printf("\n =====   func g said: Hello, I am C-styled legacy function . =============");
    printf("\n =====   func g said: Under my responsibility is not only placing something to buffers. =====");
    printf("\n ======  func g said: I am also says: 'Hello, word!' ==================="); 

    return;
};


В общем, о дорогой Гуру, ко всем вашим замечаниям можно прицепиться. С учетом Вашего тона Вам следовало бы предпринять некоторые меры, чтобы о Вас не говорили: "Чукча не Писатель, чукча КРИТИК". КРИТИК И ПИСАТЕЛЬ — разные профессии. ВЫ ТОЛЬКО КРИТИК? Еще раз повторюсь: вы так многое видите в ЧУЖОМ коде и в ЧУЖИХ подходах и решениях. Покажите нам, КАК ВЫ САМИ пишете серьезные приложения — отнюдь не тексты под копирайтом,
о нет! И никто вас не просит выложить нечто, что требует больше нескольких часов работы. Но хочется увидеть нечто такое, что позволит судить о Вашем подходе к разработке КРУПНЫХ комплексов, которые потом в процессе КОЛЛЕКТИВНОЙ разработки будут дописываться и расширяться, модифицироваться и т д — очень-очень долго. Конечно, эти подходы сильно отличаются от того, что пишется на олимпиадах или для себя. Или нет? Пожалуйста, покажите нам ВАШЕ ВЕРНОЕ "КАК НАДО" конкретно, а не расплывчато и намеками, оставляя место для фантазий . Не стоит просто указывать на массу "КАК НЕ НАДО", если вы не только критик. Дайте же нам идеал, к которому нам надлежит стремиться!
Вы же сами критики не боитесь?
Re[4]: Тестовое задание C++ win
От: KhConstantine Россия  
Дата: 07.05.10 18:12
Оценка: :))
_>PS. Шутки шутками, а вовремя пролечиться или оформить инвалидность — это лучше, чем помереть от безденежья.

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

Давайте договоримся: больше никаких сообщений друг о друге НИГДЕ и НИКОГДА.
Разве что взаимные извинения c СОГЛАСОВАННЫМИ друг с другом текстами.

Мое мыло для вас секретом не является, вашего личного я не знаю.
Через "мой круг" я вам отправил пару сообщений.
Также я вам оставил сообщение в вашем личном журнале.
Прочитайте их, потом побеседуем НЕ на форуме.
Можем даже просто по телефону — благо, мой сотик для вас — тоже не секрет.

Договорились? И, пожалуйста, воздержитесь от ЛЮБЫХ несогласованных ответов относительно моей персоны.
Ну и я воздержусь от несогласованных комментариев о вас лично и о вашей компании.
Закончим уже, OK?
Re[2]: Тестовое задание C++ win
От: sergey_cheban  
Дата: 16.01.12 13:57
Оценка: +1 :)
Приветствую героев, дочитавших эту тему до шестнадцатой страницы.

Несколько комментариев от автора вопросов:
1. Поскольку вопросы до сих пор используются для предварительного отбора кандидатов, дать "правильные ответы" или указать на конкретные ошибки я, увы, не могу.
2. Единственно верных ответов на эти вопросы не существует. На шестнадцати страницах обсуждения есть несколько вариантов, которые нас вполне устроили бы. Есть и такие, которые нам не нравятся.
3. Фактически, на каждый из вопросов нас устраивает любой ответ, который в каком-нибудь плане лучше предложенных фрагментов кода, и при этом не создаёт больше проблем, чем решает.
4. К сожалению, нам очень часто приходилось сталкиваться с ситуацией, когда явная глупость, написанная кандидатом, обозначала именно саму себя. Мы оцениваем то, что написано в ответе, не приписывая кандидатам свой взгляд на мир.
5. Большинство хороших программистов трудоустроены. 99% не трудоустроенных нам не подходят (прежде всего речь идёт о людях, у которых за спиной — один семестр "основ программирования на C/C++" и больше ничего). Мы хотим отфильтровывать 90% кандидатов на уровне предварительного отбора, и 90% оставшихся — на уровне очного собеседования. Это очень жёсткие фильтры, и не удивительно, что они иногда отбрасывают хороших разработчиков. Ничего страшного, такие разработчики найдут работу где-нибудь ещё.
6. Мы хотим увидеть хорошие ответы на оба вопроса.
7. Мы, увы, не можем задавать более сложные вопросы: хорошие разработчики на них не отвечают, а плохие нам не нужны.
8. Учитесь и развивайтесь, но не ломайте себя. Не пытайтесь подогнать ответ под то, что мы, якобы, хотим услышать. Руководствуйтесь своим здравым смыслом, своим чувством прекрасного, и вы найдёте команду единомышленников. Может быть, это будет наша команда. Но даже если нет, — может, оно и к лучшему?
Re[3]: Тестовое задание C++ win
От: Michael7 Россия  
Дата: 17.01.12 08:02
Оценка: +2
Здравствуйте, sergey_cheban, Вы писали:

_>3. Фактически, на каждый из вопросов нас устраивает любой ответ, который в каком-нибудь плане лучше предложенных фрагментов кода, и при этом не создаёт больше проблем, чем решает.


Очень многие такие тесты на собеседовании и этот в том числе имеют серьезный недостаток: они даны вне контекста и испытуемому на самом деле предлагается усовершенствовать "сферический код в вакууме." Я бы такой код без дополнительных условий вообще переписывать не стал бы Работает — и хорошо.

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

А то может первый код вообще хитрый хак чего-то или оптимизирован по быстродействию, а тут уже на форуме напредлагали и boost и смартпоинтеры, которые там возможно уместны как седло у коровы.

По второму коду можно сказать, что вообще-то есть библиотечные функции для разбора опций командной строки getopt для Unix или более универсально boost::program_options, а может этого не нужно совсем и тут важно, что внещний результат работы программы может быть одинаковым в случае отсутствия опций и в случае неотображаемого символа в аргументах.
Re[4]: Тестовое задание C++ win
От: Chorkov Россия  
Дата: 30.11.09 17:26
Оценка: 3 (1)
Здравствуйте, igna, Вы писали:

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


I>
R>>>void f( size_t n )
R>>>{
R>>> std::auto_ptr<char> a (new char[n]);
R>>> std::auto_ptr<char> b (new char[n]);
R>>> g( a.get(), b.get(), n );
R>>>}
I>


S>>Тут UB.


I>Почему?


Потому что auto_ptr::~auto_ptr вызывает delete, а не delete [].
Вызов непарного "delete-expression" == UB :

5.3.5 Delete [expr.delete]

1.
The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression.

 delete-expression:
   ::opt delete cast-expression
   ::opt delete [ ] cast-expression

The first alternative is for non-array objects, and the second is for arrays. Whenever the delete keyword is immediately
followed by empty square brackets, it shall be interpreted as the second alternative.72) The operand shall have a pointer
type, or a class type having a single non-explicit conversion function (12.3.2) to a pointer type. The result has type void.
2.
If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion
function, and the converted operand is used in place of the original operand for the remainder of this section. In either
alternative, the value of the operand of delete may be a null pointer value. If it is not a null pointer value, 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
subobject (1.8) representing a base class of such an object (clause 10). If not, the behavior is undefined.
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.73) 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. —end note ] [ Note: a pointer
to a const type can be the operand of a delete-expression; it is not necessary to cast away the constness (5.2.11) of the
pointer expression before it is used as the operand of the delete-expression. —end note ]
...

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: Тестовое задание C++ win
От: rusted Беларусь  
Дата: 30.11.09 14:33
Оценка: 1 (1)
Здравствуйте, amberovsky, Вы писали:

A>[ccode]

A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}

Проблема в том, что есть функция с ничего не говорящим именем g, для которой нет не то что комментария чего она делает, но даже названий параметров.
Re[5]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 18:56
Оценка: 1 (1)
_>давно последний раз пробовали?
А чего пробовать-то?


void f(const int* const a) {
    delete a;
}

int main() {
    f(new int);
}


Собственно говоря, очевидно, что это возможно, иначе бы удалить константный объект выделенный в куче было бы нельзя:

const Obj* const ob = new Obj(10);
delete ob; // Error????
Да здравствует мыло душистое и веревка пушистая.
Re[2]: Тестовое задание C++ win
От: 24  
Дата: 01.12.09 09:27
Оценка: 1 (1)
A_V>Теоретически, в g() могли переставить указатели на что-нибудь другое, и не удалить то, на что они указывали.
Не могли там такого сделать. Внутри этой функции она бы переставила свои локальные копии указателей, а не исходные. Чтоб была возможность переставить исходные указатели, описание функции должно быть таким:
void g( char * &, char * &, size_t );
Re[7]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 02.12.09 22:58
Оценка: 1 (1)
Здравствуйте, alexander_st, Вы писали:

_>Из каких соображений тогда ну скажем ф-я std::string c_str() возвращает const char* а не просто char* ? может для того , что бы показать, что удалять этот буфер не надо?


Знаешь, есть дофига способов abuse. Например, получить указатель на неконстантный объект в стеке или статике — и попробовать его удалить. И никто не пикнет, кроме менеджера кучи перед смертью.
Ещё можно попробовать удалить delete[] &vec.front() — вполне себе неконстантный массив, рамещённый на куче... Ты просто украдёшь право владения, которое было у вектора.

Язык С++ в явном виде не декларирует права владения указуемыми объектами. Иначе бы указатель на стековый объект и указатель на объект, созданный на куче, должны были быть разного типа!!!
Это можно только гигиеной и дисциплиной обеспечить. Гигиена — это, как минимум, умными указателями с политиками.
Беда в том, что голый указатель предоставляет сразу все права (ну только с константностью есть ограничение на изменение объекта). А следовательно, всегда остаётся возможность для нецелевого использования. А следовательно — без дисциплины никуда.
Перекуём баги на фичи!
Re[4]: Тестовое задание C++ win
От: sergey_cheban  
Дата: 06.05.10 11:59
Оценка: 1 (1)
Здравствуйте, KhConstantine, Вы писали:

KC>Блин... вызов delete как раз только при NULL... Ляп, однако. Конструкция "если указатель нулл, то сделать что-то" в пальцы въелась, однако...

И таких ляпов у Вас — 100% осмысленного кода. Вот ещё один:

try
{
    pGFuncCaller = new GFuncCaller_STL(oSubSystem);
}
catch(exception &e)
{
    oSubSystem.log(e); 
        pGFuncCaller = NULL;
};
oSubSystem.execute(pGFuncCaller);

delete pGFuncCaller;
pGFuncCaller = NULL;

Чем кончится вызов oSubSystem.execute(NULL) — посмотрите сами.

А вот другой: класс SomeSubSystem имеет виртуальные функции, но при этом не имеет ни предков, ни наследников. Какая муза вас посетила и почему она ушла раньше времени — загадка.

KC> Хотел напомнить, что удаление на указателе с NULL — НЕ вызывает exception, а перехват исключений можно делать не на атомарном уровне...

Кому Вы хотели это напомнить? Мне? Спасибо, я уже в курсе.

KC>Но удивлен, что супер-пупер спецы из доктора веба нашли время залезть, да скачать... Вы же говорили, что код такого ничтожества, как я, вас не интересует и задание, которое я написал для другой конторы, нефиг вам присылать?

Но ведь сейчас речь идёт о другом коде — о проекте, созданном 1 мая (это дата stdafx.cpp. Cобеседование, напомню, состоялось 29 апреля), в котором упоминается торговая марка моей компании. Как тут удержаться от любопытства?

KC>Господин гуру, а своим кодом нас, сирых и убогих недоучек, вы не могли бы порадовать?

Вы меня точно ни с кем не путаете? У меня нет больших объёмов собственного кода под свободными лицензиями. Моё участие в open source разработке ограничивается вот этим скромным вкладом: http://groups.google.com/group/fardev/browse_thread/thread/94ead2b8004314e4?pli=1

KC>Вы вообще хоть что-нибудь пишете?

Да, пишу. Нет, не покажу.

KC>Разве что на пресловутом собеседовании, когда я вам объяснял архитектуру приложения, которое вычищал от ошибок на предыдущей работе — ляпнули,

KC>что АСИНХРОННУЮ обработку АСИНХРОННЫХ запросов из МНОЖЕСТВЕННЫХ источников, причем с несовпадением порядка ответов с порядком запросов,
KC>лучше делать в один поток...
Уж не знаю, правильно ли я понял Вас, но Вы меня в тот момент точно поняли неправильно. По сути, в ответ на Ваше утверждение "поскольку у нас есть много клиентов, нам необходимо много потоков" я предложил Вам однопоточный вариант. Преимущества у этого варианта есть, недостатки тоже, и разговор мог бы получиться интересным. Но — не судьба.

KC>Кстати, в ваших словах про локаль — одна ошибка и, что для вас типично, масса неопределенности. Раз такие крутые — попробуйте выяснить сами.

Угу, есть. Тогда тем более не понимаю, зачем Вы приписали нам свои заслуги.
Re[9]: Тестовое задание C++ win
От: duncanmclaud  
Дата: 17.01.12 09:48
Оценка: 1 (1)
Здравствуйте, Michael7, Вы писали:

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



A>>Ну раз это доктор Вэб, то

A>>1. Я бы ответил что в функции f n не проверяеться размер n ,можно запросить столько памяти что не сможет выделить система

M>А если задача работать быстро, размер n заведомо не превосходит доступной памяти, а лишние проверки только затормозят?


A>>2. Стопудово что размер argv[1] не проверяеться, программа становиться уязвимой


M>Тогда еще надо проверять и все возможные модификаторы в строке ввода, вообще есть готовые функции для разбора опций, чтобы велосипед не изобретать. А тут может быть программа — это затычка для какого-нибудь скрипта и говорить про уязвимость бессмысленно.


M>В общем, как я уже написал, на практике без дополнительных не видно смысла что-то с этим делать, тест, строго говоря, некорректный.


даже не знаю...
Но данные задания, позволяют посмотреть как думает человек, обычно задание дается, и просится озвучивать что видит, что нужно изменить, и т.д.
Не обязательно правильно ответить, правильных ответов обычно нету, имеется ввиду один правильный ответ и других нет, ответов может быть много, и каждый по своему правильный, но по размышлениям примерно видно что за инженер, обычно цель не проверить знания, а проверить способность мыслить, способность видеть потенциальные ошибки, и т.д. Для инженера самое главное не помнить названия всех функций,и что они делают, а умение мыслить, а знания приобретаются по ходу работу, если чего-то инженер не знает, он должен знать где найти ответ, взять книгу или банально гуглонуть, найти ответ и применить его на практике. Зачастую студент без опыта работы но думающий, потенциально принесет больше пользы, чем просто ходячий справочник с опытом работы, а таких хватает, на собеседовании все отвечает, а на деле с простой задачей, где нужно именно думать и искать решение не может справиться.
Это мое мнение ))
Re[3]: Тестовое задание C++ win
От: remark Россия http://www.1024cores.net/
Дата: 30.11.09 12:35
Оценка: +1
Здравствуйте, Smal, Вы писали:

R>>
R>>void f( size_t n )
R>>{
R>> std::auto_ptr<char> a (new char[n]);
R>> std::auto_ptr<char> b (new char[n]);
R>> g( a.get(), b.get(), n );
R>>}
R>>


S>Тут UB.


Да-да, точно, есть такая фигня. Ну тогда стандартными средствами лучше всего наверное std::vector<>.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[6]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 19:01
Оценка: -1
_>а если эта ф-я экспортируется из dll она бы тоже принимала 2 вектора?
Дело не в экспорте, а в языке. Зачем С++ функции принимать указатели, если можно векторы?

_>а исключение по выделению памяти или по какому нить доступу по кривому указателю она тоже не может кинуть?

С++ исключение, если она написана на С — не может.
Да здравствует мыло душистое и веревка пушистая.
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[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: Тестовое задание C++ win
От: Alexey_VL  
Дата: 01.12.09 09:01
Оценка: -1
Здравствуйте, amberovsky,

Теоретически, в g() могли переставить указатели на что-нибудь другое, и не удалить то, на что они указывали. Лечится с помощью void g( char * const, char * const, size_t ); Хотя в реальных проектах пока ни разу не встречал такой защиты.
Мафиозная диктатура это нестабильность. Если не мафиозная диктатура, то Конституция и демократия.
Re[7]: Тестовое задание C++ win
От: Bell Россия  
Дата: 01.12.09 11:17
Оценка: +1
Здравствуйте, Kernan, Вы писали:

K>Ты не можешь гарантировать то, что delete не переопределён и работает корректно.


Ну почему же
Перегрузить можно operator delete, а поведение delete expression (о котором и идет речь) для нулевого указателея четко специфицировано стандартом, и

has no effect (5.3.5/2)

Любите книгу — источник знаний (с) М.Горький
Re: Тестовое задание C++ win
От: carpenter Голландия  
Дата: 01.12.09 15:24
Оценка: -1
Здравствуйте, amberovsky, Вы писали:

блин — я вообще слепой — все норм по моему — единтственно — можно труями кэтчами обложить ,
но это уже коде стайлинг



A>
A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}

A>2.
A>int main(int argc, char* argv[])
A>{
A> if( argc > 1 )
A>  printf( argv[1] );
A> return 0;
A>}

A>
Весь мир — Кремль, а люди в нем — агенты
Re[7]: Тестовое задание C++ win
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 01.12.09 15:28
Оценка: :)
Здравствуйте, Кодт, Вы писали:

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


K>>вот только вопрос есть, тебе на вход приходит 0, а на вход функции g ты передёшь 1. Подмена понятий, однако. Хотя код неплох, есть чему поучится


К>Если ты присмотришься внимательно, то заметишь: на вход g приходит 0.


К>Но в конструкторы векторов действительно приходит 1. Это нужно затем, чтобы эмулировать поведение new char[0].

К>Дело в том, что char* p = new char[0] — это валидный ненулевой неразыменовываемый (обрати внимание на эти три слова!) указатель за конец массива.

К>Вектор же не оперирует указателями. Он отдаёт итераторы, разыменовывая которые, получаем ссылки (*v.begin()); или же сразу ссылки (v[0], v.front()).

К>Потом ссылку можно восстановить до указателя (&v.front()) и, прибавив размер, получить указатель за конец массива (&v.front()+v.size()).
К>Итератор конца (v.end()) неразыменовываемый, *v.end() — UB. Так что лобовое решение &*v.end() не подходит.

К>Соответственно, если вектор нулевого размера, v.begin()==v.end(), получить указатель не получится.


К>Можно, конечно, набраться наглости и сказать v.resize(0); char*p=&v.front(); — но, повторю, это неопределённое поведение. Например, в отладочной версии STL ест шанс схлопотать assert(false).


К>Но даже если не будет assertion fault, можем получить p==NULL (раз размер нулевой, то внутренний массив не выделен, а внутренние указатели выставлены в некое дефолтное, т.е. нулевое значение).

К>То есть, указатель для g() будет валидный, неразыменовываемый (а мы и не собирались разыменовывать — n==0), но — нулевой.

К>Возможно, что g() способно работать и с набором параметров g(NULL,NULL,0). Этого из начальных условий задачи мы не знаем. Поэтому я и предложил трюк с max(n,1).

К>Тем более, что нагрузка на кучу для new char[0] и new char[1] (внутри vector) — почти одинаковая.
Получается, что ты предполагаешь, что функция g проверяет n >= 0, чего может и не быть. Более того, неизвестный код может длелать какие-то действия в случае (NULL, NULL, 0).
Sic luceat lux!
Re[2]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 01.12.09 16:01
Оценка: +1
Здравствуйте, carpenter, Вы писали:

C>блин — я вообще слепой — все норм по моему — единтственно — можно труями кэтчами обложить ,

C>но это уже коде стайлинг

Угу, слепой Среди 70 ответов выше были разные мнения и советы, и про "не всё норм", и про "можно без try-catch"...
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[8]: Тестовое задание C++ win
От: maykie Россия  
Дата: 02.12.09 12:10
Оценка: +1
в g(NULL,NULL,0). Этого из начальных условий задачи мы не знаем. Поэтому я и предложил трюк с max(n,1).
К>>Тем более, что нагрузка на кучу для new char[0] и new char[1] (внутри vector) — почти одинаковая.
K>Получается, что ты предполагаешь, что функция g проверяет n >= 0, чего может и не быть.

Не понял зачем ей это проверять. n всегда >= 0. size_t беззнаковый.
Re[4]: Тестовое задание C++ win
От: труженик села  
Дата: 03.12.09 11:24
Оценка: +1
Здравствуйте, amberovsky, Вы писали:

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


C>>>ничего g не может испортить.


_>>правда? а если попробовать так:


_>>
_>>g(char*a , char* b, size_t)
_>>{
_>>    delete a;
_>>    delete[] b;
_>>}
_>>


A>Да, это я и имел ввиду под "испортить"


Для решения такой ситуации надо переделывать саму ф-ию g, что выходит за рамки этого задания.
Re[7]: Тестовое задание C++ win
От: Head Ache  
Дата: 04.12.09 06:26
Оценка: +1
Здравствуйте, Vamp, Вы писали:

_>>а если эта ф-я экспортируется из dll она бы тоже принимала 2 вектора?

V>Дело не в экспорте, а в языке. Зачем С++ функции принимать указатели, если можно векторы?

_>>а исключение по выделению памяти или по какому нить доступу по кривому указателю она тоже не может кинуть?

V>С++ исключение, если она написана на С — не может.

А зачем C функции оператор new?
Этот аккаунт покинут.
Re[2]: Тестовое задание C++ win
От: Tesh США  
Дата: 04.12.09 14:05
Оценка: +1
Здравствуйте, любой, Вы писали:

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


Л>Тут по существу уже сказали. А меня в таком коде всегда прикалывает, почему два блока нельзя за раз выделить:


Л>char *a = new char[n*2];

Л>char *b = a + n;
Л>g( a, b, n );
Л>delete [] a;

Насколько я понимаю в этом случае нужен будет в два раза больший непрерывный блок памяти, который найти меньше шансов, чем два поменьше
Re[3]: Тестовое задание C++ win
От: любой  
Дата: 09.12.09 11:54
Оценка: :)
Здравствуйте, Tesh, Вы писали:

Л>>char *a = new char[n*2];

Л>>char *b = a + n;
Л>>g( a, b, n );
Л>>delete [] a;

T>Насколько я понимаю в этом случае нужен будет в два раза больший непрерывный блок памяти, который найти меньше шансов, чем два поменьше


Зато в сумме потребуется чуть меньше памяти, т.к. накладные расходы на один блок меньше.
художников никогда не обижал
Re[4]: Тестовое задание C++ win
От: tealex  
Дата: 30.12.09 00:12
Оценка: +1
видимо для отсева работодателя )
хана
Re: Тестовое задание C++ win
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 11.01.10 14:08
Оценка: :)
Здравствуйте, amberovsky, Вы писали:

A>При попытке устроится в одну фирму прислали "удалённое" тестовое задание.


1. Какие проблемы Вы видите в этих фрагментах кода


2. Как предлагаете их решать?

Вычислить автора и фтопку его.

А так же всех, кто сидел слева и справа от него — вдруг они уже заразились ...

-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[4]: Тестовое задание C++ win
От: nazavrik Россия  
Дата: 05.05.10 21:45
Оценка: +1
Здравствуйте, KhConstantine,

чем Вас обидели?
Re[4]: Тестовое задание C++ win
От: TarasKo Голландия  
Дата: 05.05.10 22:31
Оценка: +1
Советую забить У меня тоже бывали случаи, когда после собеседования хотелось кричать и махать кулаками, мне казалось что со мной поступили не справедливо, я тоже писал на рсдн например здесь
http://www.rsdn.ru/forum/philosophy/2971148.aspx
Автор: TarasKo
Дата: 30.05.08


Теперь я по другому к этому отношусь. Конечно собеседующие могут быть не идеальны, но эта та часть мира которую мне не изменить. Зато я могу изменить себя. Могу читать больше книжек, могу учиться разговаривать по другому, так что бы не возникало желания меня гнобить Вспоминая то собеседование, могу сказать что я был очень самоуверен, вел себя соответствующе, быстро и слишком подробно ответил на вводные вопросы про с++, мне иногда казалось, что собеседующий меня не понимает. Видимо этим его разозлил

Собеседование это ж не только проверка на знание, но и проверка насколько я коммуникабелен. Если так получилось что за время собеседование я разозлил интервьюера, то это тоже повод задуматься. Меня не возьмут на работу даже если я буду ВСЁ знать, ведь как потом со мной работать.

Вообщем я из того случая надеюсь извлёк свои уроки Вам сооветую сделать тоже самое и не на кого не злится
Re[2]: Тестовое задание C++ win
От: KhConstantine Россия  
Дата: 07.05.10 04:18
Оценка: -1
Здравствуйте, sergey_cheban, Вы писали:

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


A>>При попытке устроится в одну фирму прислали "удалённое" тестовое задание.

_>Раз уж это задание попало на RSDN и стало предметом обсуждения, позвольте несколько комментариев от автора.

_>1. Целью этого задания является предварительный отсев кандидатов. Если кандидат нормально ответил на вопросы, мы приглашаем его на собеседование. Как показывает практика, на этом этапе отсеивается примерно половина кандидатов, что серьёзно экономит наше время.

_>2. Основным требованием к заданию является простота его выполнения (для тех кандидатов, которые нам подходят). Сложные задания отпугивают кандидатов, а нам это не нужно.
_>3. Никаких "единственно правильных ответов" не существует. Ответы рассматривают разработчики, а не отдел кадров. На этом этапе мы готовы принять любой вариант, который решает больше проблем, чем создаёт.
_>4. Мы тоже иногда ошибаемся, причём при наличии сомнений предпочитаем отказать кандидату. В конце концов, каждый ошибочно принятый на работу человек обходится нам в несколько десятков тысяч рублей чистого убытка, а каждый ошибочно отвергнутый — найдёт себе применение где-нибудь в другом месте.
_>5. Если кандидат в процессе чтения этой ветки узнаёт много нового и интересного для себя — это верный признак того, что ему ещё есть чему поучиться до того, как он сможет претендовать на работу у нас.

>> несколько десятков тысяч рублей чистого убытка

Понятен стандартный уровень ваших зарплат.
>> до того, как он сможет претендовать на работу у нас
Да, каждый сам устанавливает планку. И компании уровня "несколько десятков тысяч рублей"/брэнд из разряда "а разве они все еще существуют?" — тоже.

Ну что же, из Ваших прочих сообщений видно, что лично Ваш код проанализировать не выйдет. Жаль.Везде можно найти нечто интересное и поучительное.
В частности, здесь и сейчас даю наводку на популярные книги Эрика Берна, основателя транзакционного анализа: "Игры, в которые играют люди" и "Люди, в которые играют в игры". Форум — программистский, наводка — на работы по психологии, полезные всем, чья существенная часть работы связана с взаимодействием с другими людьми.
С другой стороны, есть такая крайне полезная техника: "инспекция кода/дизайна/документа равными". Двойной эффект: огромный плюс в плане передачи знаний + очень простой и очень дешевый, но очень эффективный способ повышения качества кода. Соответственно и производительности труда в целом (и программисты быстрее и полнее изучают систему/быстрее работают за счет снижения затрат на собственные исследования кода, и раннее обнаружение ошибок означает снижение затрат за счет сокращения цикла код->тестирование-> CR -> анализ -> исправление ). Практикуется Моторолой с ее "шесть сигм" и массой других брэндов. Заключается в обязательном объяснении разработчиком своих исправлений группе коллег. Но требует соблюдения определенных норм общения — в частности, обязательно исключительно общение в благожелательно-нейтральном/безэмоциональном стиле ("взрослый->взрослый", определение проблемы/сбор информации/поиск решения). Иначе — конфликты, и исполнители думают не столько о работе, сколько прокручивают в голове разные внутренние диалоги.

В адаптированном виде описание применения транзакционного анализа нередко включается в ученики по управлению проектами, team building, etc
В соответствии с этой терминологией: Практически все транзакции идут у Вас с позиции "родитель критикующий". Позиция известна, как наиболее конфликтная и наименее продуктивная. Человек, общающийся с этой позиции, в своем восприятии транслирует все ответные транзакции, к какому бы типу они ни принадлежали в действительности, исключительно в два типа: "Ребенок послушный->Родитель критикующий" и "ребенок непослушный-> родитель критикующий". Второй тип вызывает отторжение. Так, данный абзац оформлен в нейтральном стиле, а какие чувства он вызывает у вас? Замечу, что на собеседовании вы тоже получали с моей стороны транзакции "взрослый->взрослый".
Конфликтная природа позиции "Родитель критикующий" вызвана прежде всего тем, что для человека в позиции "родитель критикующий" единственно приемлемой ответной транзакцией является транзакция с позиции "ребенок послушный". Соответственно собеседнику навязывается позиция "ребенок". Поскольку для полноценного взрослого человека, без заниженной самооценки, позиция "ребенок послушный" является крайне невыгодной, идет отторжение невыгодного шаблона поведения на инстинктивном уровне. Если же по каким-либо причинам человек вынужден следовать шаблону "ребенок послушный" долгое время, рискует в этой позиции и застрять, заполучив в итоге заниженную самооценку. Что крайне вредно для продуктивности — человек слишком боится ошибиться, следует принципу не ошибается лишь тот, кто ничего не делает.

В общем, при коллективной работе оптимальным признается исключительно "взрослый->взрослый", ограниченно допустимым (если собеседник сам переключился в позицию "ребенок", что типично при обращении к человеку с более высоким рангом) — "родитель поддерживающий/покровительствующий".

Что интересно: человек, для которого типична позиция "родитель критикующий", зачастую всеми силами избегает что-либо делать САМ из-за инстинктивного страха совершить ошибку — слишком привык к своей позиции и слишком хорошо знает, что чувствуют его собеседники. Тем более, что этот шаблон поведения зачастую является результатом обезъянничанья со стороны человека, для которого ранее был типичен шаблон "ребенок послушный".

Если в вашей компании большая текучка и проблема с подбором кадров — возможно, это небольшое эссе укажет на одну из причин. Возможно, в схеме "может/ему разрешено/хочет" требование следовать шаблону "послушный ребенок" оказалось в "может"
Re[3]: Тестовое задание C++ win
От: minorlogic Украина  
Дата: 16.01.12 14:18
Оценка: +1
Мне тон сообщения показался невежливым.
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[2]: Тестовое задание C++ win
От: midl  
Дата: 16.01.12 20:05
Оценка: +1
Здравствуйте, sergey_cheban, Вы писали:
_>5. Если кандидат в процессе чтения этой ветки узнаёт много нового и интересного для себя — это верный признак того, что ему ещё есть чему поучиться до того, как он сможет претендовать на работу у нас.
C учетом предлагаемой зарплаты, других кандидатов вы наврятле увидите усебя на собеседовании
Re[4]: Тестовое задание C++ win
От: sergey_cheban  
Дата: 17.01.12 12:26
Оценка: :)
_>> 3. Фактически, на каждый из вопросов нас устраивает любой ответ, который в каком-нибудь плане лучше предложенных фрагментов кода, и при этом не создаёт больше проблем, чем решает.
M> Очень многие такие тесты на собеседовании и этот в том числе имеют серьезный недостаток: они даны вне контекста и испытуемому на самом деле предлагается усовершенствовать "сферический код в
M> вакууме." Я бы такой код без дополнительных условий вообще переписывать не стал бы Работает — и хорошо.
Представьте, что вышеуказанные фрагменты кода достались Вам в наследство от программиста, уволенного за профнепригодность, и у Вас есть немного времени на рефакторинг именно этих фрагментов.

M> Как можно говорить, что усовершенствованный код должен решать больше проблем, чем создает, если даже достоверно неясно какого рода проблемы имели место?

Наличие проблем — это часть вопроса. Исправляйте те проблемы, которые видите. Считайте, что Вы — последний человек, который стоит между этими фрагментами кода и реальной эксплуатацией в какой-нибудь life-critical system.

M> А то может первый код вообще хитрый хак чего-то или оптимизирован по быстродействию, а тут уже на форуме напредлагали и boost и смартпоинтеры, которые там возможно уместны как седло у коровы.

M> По второму коду можно сказать, что вообще-то есть библиотечные функции для разбора опций командной строки getopt для Unix или более универсально boost::program_options, а может этого не нужно
M> совсем и тут важно, что внещний результат работы программы может быть одинаковым в случае отсутствия опций и в случае неотображаемого символа в аргументах.
Ради бога. Если Вы считаете, что от использования буста, смартпоинтеров, getopt или чёрта в ступе программа в чём-то выиграет, то пожалуйста, используйте их. Только напишите, в чём программа, по Вашему мнению, выиграла.
Re[4]: Тестовое задание C++ win
От: TimurSPB Интернет  
Дата: 18.01.12 11:05
Оценка: +1
Опацэ! Ну и обстановочка в этих ваших докторвебах
Элементарная вежливость и та отсутствует.
Make flame.politics Great Again!
Re: Тестовое задание C++ win
От: Visor2004  
Дата: 24.01.12 13:28
Оценка: :)
Здравствуйте, amberovsky, Вы писали:

A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?


надо было ответить: гавнакод, того кто написал это выгнать нахер, взять меня и я перепишу вам по людски
Помните!!! ваш говнокод кому-то предстоит разгребать.
Тестовое задание C++ win
От: amberovsky  
Дата: 30.11.09 11:17
Оценка:
Здравствуйте.
При попытке устроится в одну фирму прислали "удалённое" тестовое задание.



Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
1.
void g( char *, char *, size_t );
void f( size_t n )
{
 char *a = new char[n];
 char *b = new char[n];
 g( a, b, n );
 delete [] b;
 delete [] a;
}

2.
int main(int argc, char* argv[])
{
 if( argc > 1 )
  printf( argv[1] );
 return 0;
}


Я ответил так:
1. new может не сработать, нужно добавить, например, try/catch. Кроме того, g может "испортить" указатели (как тут просто решить я не знаю)
2. В аргументе командной строки может встретиться символ % или \, что будет расценено printf как специальный символ.
Если следующие символы совпадут с какой-либо спецификацией формата (для % или \), то в данном случае для % — UB, для \ — произойдёт подстановка.
Решение — printf("%s", argv[1]);
Ещё можно проверить что printf действительно напечатало нужное количество символов.


В итоге мне отказали.
В чём я ошибся или чего важного не указал?

07.05.10 02:19: Перенесено из 'C/C++'
Re: Тестовое задание C++ win
От: remark Россия http://www.1024cores.net/
Дата: 30.11.09 11:42
Оценка:
Здравствуйте, amberovsky, Вы писали:

A>2. В аргументе командной строки может встретиться символ % или \, что будет расценено printf как специальный символ.

A>Если следующие символы совпадут с какой-либо спецификацией формата (для % или \), то в данном случае для % — UB, для \ — произойдёт подстановка.
A>Решение — printf("%s", argv[1]);

Тут да, неизвестные строки всегда надо выводить как printf("%s", str).


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Тестовое задание C++ win
От: Bell Россия  
Дата: 30.11.09 11:53
Оценка:
Здравствуйте, amberovsky, Вы писали:

A>
A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}

A>2.
A>int main(int argc, char* argv[])
A>{
A> if( argc > 1 )
A>  printf( argv[1] );
A> return 0;
A>}

A>


A>Я ответил так:

A>1. new может не сработать, нужно добавить, например, try/catch. Кроме того, g может "испортить" указатели (как тут просто решить я не знаю)
new может кинуть исключение, g тоже может кинуть исключение, соответственно могут возникнуть утечки. В g невозможно проверить "валидность" указателей и длину блоков. Насчет второго можно возразить, что ответственность лежит на пользователе функции g, но ИМХО assert в функции не помешал бы.
Обе эти проблемы можно решить, если в качестве параметров g использовать std::vector<char>.

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

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



A>2. В аргументе командной строки может встретиться символ % или \, что будет расценено printf как специальный символ.

A>Если следующие символы совпадут с какой-либо спецификацией формата (для % или \), то в данном случае для % — UB, для \ — произойдёт подстановка.
A>Решение — printf("%s", argv[1]);

В общем верно.



A>В итоге мне отказали.

A>В чём я ошибся или чего важного не указал?
Любите книгу — источник знаний (с) М.Горький
Re: Тестовое задание C++ win
От: Caracrist https://1pwd.org/
Дата: 30.11.09 12:03
Оценка:
Здравствуйте, amberovsky, Вы писали:

A>Здравствуйте.

A>При попытке устроится в одну фирму прислали "удалённое" тестовое задание.



A>
A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}


A>


A>Я ответил так:

A>1. new может не сработать, нужно добавить, например, try/catch. Кроме того, g может "испортить" указатели (как тут просто решить я не знаю)

ничего g не может испортить.

A>В итоге мне отказали.

A>В чём я ошибся или чего важного не указал?
~~~~~
~lol~~
~~~ Single Password Solution
Re[2]: Тестовое задание C++ win
От: alexander_st Россия  
Дата: 30.11.09 12:23
Оценка:
Здравствуйте, Caracrist, Вы писали:

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


C>ничего g не может испортить.


правда? а если попробовать так:

g(char*a , char* b, size_t)
{
    delete a;
    delete[] b;
}

ПыСы: разные варьянты delete от нечего делать, но понятно что при выходе из ф-и g и попытке сделать очередной delete будет маленькая попа
Re[3]: Тестовое задание C++ win
От: amberovsky  
Дата: 30.11.09 12:34
Оценка:
Здравствуйте, alexander_st, Вы писали:

C>>ничего g не может испортить.


_>правда? а если попробовать так:


_>
_>g(char*a , char* b, size_t)
_>{
_>    delete a;
_>    delete[] b;
_>}
_>


Да, это я и имел ввиду под "испортить"
Re[2]: Тестовое задание C++ win
От: amberovsky  
Дата: 30.11.09 12:35
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Главная проблема — это не тест по C++


Это удалённый пре-тест для отсева.
Re[3]: Тестовое задание C++ win
От: amberovsky  
Дата: 30.11.09 12:39
Оценка:
Здравствуйте, Smal, Вы писали:

R>>Если доступен scoped_ptr<>, то лучше использовать его.


S>Ну, тогда уж

S>
S>void f( size_t n )
S>{
S> std::vector<char> a (n);
S> std::vector<char> b (n);
S> g( &a[0], &b[0], n );
S>}
S>


Насколько это естественно? По-моему это слишком сложно для обычной передачи параметров.

S>или


S>
S>void f( size_t n )
S>{
S> boost::scoped_array<char> a (new char[n]);
S> boost::scoped_array<char> b (new char[n]);
S> g( a.get(), b.get(), n );
S>}
S>


Использовать boost в таких заданиях нормально?

p.s. На второй вопрос я ответил правильно, в первом так себе. Почему же отказали?
Re[4]: Тестовое задание C++ win
От: SaZ  
Дата: 30.11.09 12:57
Оценка:
Здравствуйте, amberovsky, Вы писали:

A>p.s. На второй вопрос я ответил правильно, в первом так себе. Почему же отказали?


Если задание удалённое — то неправильно. А на собеседовании попросили бы аргументировать. Почему — написано ниже.
Re[4]: Тестовое задание C++ win
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 30.11.09 14:03
Оценка:
Здравствуйте, amberovsky, Вы писали:


S>>Ну, тогда уж

S>>
S>>void f( size_t n )
S>>{
S>> std::vector<char> a (n);
S>> std::vector<char> b (n);
S>> g( &a[0], &b[0], n );
S>>}
S>>


A>Насколько это естественно? По-моему это слишком сложно для обычной передачи параметров.


Это не очень красивая, но совершенно стандартная идиома.
Скотт Мейерс, Эффективное использование STL, Item 16

Item 16. Know how to pass vector and string data to legacy APIs.

Since C++ was standardized in 1998, the C++ elite haven't been terribly subtle in their attempt to nudge programmers away from arrays and towards vectors. They've been similarly overt in trying to get developers to shift from char* pointers to string objects. There are good reasons for making these changes, including the elimination of common programming errors (see Item 13) and the ability to take full advantage of the power of the STL algorithms (see. e.g., Item 31).
Still, obstacles remain, and one of the most common is the existence of legacy C APIs that traffic in arrays and char* pointers instead of vector and string objects. Such APIs will exist for a long time, so we must make peace with them if we are to use the STL effectively.
Fortunately, it's easy. If you have a vector v and you need to get a pointer to the data in v that can be viewed as an array, just use &v[0]. For a string s, the corresponding incantation is simply s.c_str(). But read on. As the fine print in advertising often points out, certain restrictions apply.
Given
vector<int> v;


the expression v[0] yields a reference to the first element in the vector, so &v[0] is a pointer to that first element. The elements in a vector are constrained by the C++ Standard to be stored in contiguous memory, just like an array, so if we wish to pass v to a C API that looks something like this.
void doSomething(const int* pInts, size_t numlnts);
we can do it like this:
doSomething(&v[0], v.size());

Maybe. Probably. The only sticking point is if v is empty. If it is, v.size() is zero, and &v[0] attempts to produce a pointer to something that does not exist. Not good. Undefined results. A safer way to code the call is this:
if (!v.empty()) {
doSomething(&v[0], v.size());
}

If you travel in the wrong circles, you may run across shady characters who will tell you that you can use v.begin() in place of &v[0], because (these loathsome creatures will tell you) begin returns an iterator into the vector, and for vectors, iterators are really pointers. That's often true, but as Item 50 reveals, it's not always true, and you should never rely on it. The return type of begin is an iterator, not a pointer, and you should never use begin when you need to get a pointer to the data in a vector. If you're determined to type v.begin() for some reason, type &*v.begin(), because that will yield the same pointer as &v[0], though it's more work for you as a typist and more obscure for people trying to make sense of your code. Frankly, if you're hanging out with people who tell you to use v.begin() instead of &v[0], you need to rethink your social circle.

...

Re[5]: Тестовое задание C++ win
От: amberovsky  
Дата: 30.11.09 14:54
Оценка:
Здравствуйте, SaZ, Вы писали:

SaZ>Если задание удалённое — то неправильно. А на собеседовании попросили бы аргументировать. Почему — написано ниже.


Вы считаете ошибку со слешем причиной отказать?
Re[3]: Тестовое задание C++ win
От: Sergey Chadov Россия  
Дата: 30.11.09 15:55
Оценка:
Здравствуйте, Vamp, Вы писали:

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

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

Каким образом она это указывает?
--
Sergey Chadov

... << RSDN@Home 1.2.0 alpha rev. 685>>
Re[6]: Тестовое задание C++ win
От: SaZ  
Дата: 30.11.09 16:04
Оценка:
Здравствуйте, amberovsky, Вы писали:

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


SaZ>>Если задание удалённое — то неправильно. А на собеседовании попросили бы аргументировать. Почему — написано ниже.


A>Вы считаете ошибку со слешем причиной отказать?


Не только в слэше делать, но зачем вспоминать, если не уверен в правильности? Вспомнился случай с одного экзамена, когда преподаватель как раз подобными вопросами всех валил. А причина была простая: непонимание группой того, что \n — это один символ, понятный лишь компилятору и не принимаемый извне.
Признаю, что возможно немного погорячился с оценкой. Цепляться в этом случае или нет, так сказать, человеко-зависимо. Мои преподаватели бы зацепились (на собеседовании, а на экзамене — тем более).
Re: Тестовое задание C++ win
От: neFormal Россия  
Дата: 30.11.09 16:18
Оценка:
Здравствуйте, amberovsky, Вы писали:

A>
A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}
A>


инициализация строк, какой нить const char* или std::string в параметрах g и то, что по хорошему надо в g передать 2 размера, а не один (если это не strcpy )..
также, как вариант ответа, сойдёт "этот код хз что делает, поэтому его надо переписать по человечески"..
...coding for chaos...
Re[2]: Тестовое задание C++ win
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 30.11.09 16:28
Оценка:
Здравствуйте, Kernan, Вы писали:
A>>
A>>2.
A>>int main(int argc, char* argv[])
A>>{
A>> if( argc > 1 )
A>>  printf( argv[1] );
A>> return 0;
A>>}
A>>

K>Не смущает, что нумерация массива начинается с 0, и в argc[0] == 'имя исполняемого файла'?
K>Т.е. argc всегда > 0
чо-то я упустил . всё верно )
Sic luceat lux!
Re[3]: Тестовое задание C++ win
От: igna Россия  
Дата: 30.11.09 16:41
Оценка:
Здравствуйте, Smal, Вы писали:

R>>void f( size_t n )
R>>{
R>> std::auto_ptr<char> a (new char[n]);
R>> std::auto_ptr<char> b (new char[n]);
R>> g( a.get(), b.get(), n );
R>>}


S>Тут UB.


Почему?
Re[2]: Тестовое задание C++ win
От: igna Россия  
Дата: 30.11.09 16:47
Оценка:
Здравствуйте, Kernan, Вы писали:

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


Здесь дублируются оба delete, такой код трудно сопровождать.
Re[5]: Тестовое задание C++ win
От: alexander_st Россия  
Дата: 30.11.09 18:46
Оценка:
Здравствуйте, Vamp, Вы писали:

SC>>Каким образом она это указывает?

V>Способом передачи параметров. Если бы она была написана на С++, она бы принимала два вектора.
а если эта ф-я экспортируется из dll она бы тоже принимала 2 вектора?
а исключение по выделению памяти или по какому нить доступу по кривому указателю она тоже не может кинуть?
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
От: 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
От: 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[2]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 01.12.09 10:35
Оценка:
Здравствуйте, Alexey_VL, Вы писали:

A_V>Теоретически, в g() могли переставить указатели на что-нибудь другое, и не удалить то, на что они указывали. Лечится с помощью void g( char * const, char * const, size_t ); Хотя в реальных проектах пока ни разу не встречал такой защиты.


Наложение константности на данные, передаваемые по значению (собственно указатели) — большого смысла не несёт.
Всё равно наружу любые изменения не просочатся.
А внутри — элементарно снимается
void g(char* const a)
{
    char* aa = a;
    .......
    aa = bbbb;
    .......
}

Но что в этом ужасного — непонятно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[6]: Тестовое задание C++ win
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 01.12.09 11:07
Оценка:
Здравствуйте, andrey.desman, Вы писали:

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


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

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

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

Ты не можешь гарантировать то, что delete не переопределён и работает корректно.
Sic luceat lux!
Re[3]: Тестовое задание C++ win
От: Alexey_VL  
Дата: 01.12.09 11:15
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Наложение константности на данные, передаваемые по значению (собственно указатели) — большого смысла не несёт.


Это я ступил. Просто была давно подуманная мысль про char * const , что она так работает. Поскольку в реальности эта мысль не применялась и как следствие не продумывалась заново, она до сегодняшняего дня лежала в моске как истинная
Мафиозная диктатура это нестабильность. Если не мафиозная диктатура, то Конституция и демократия.
Re[4]: Тестовое задание C++ win
От: Alexey_VL  
Дата: 01.12.09 11:17
Оценка:
Имеется ввиду — char * const для передачи данных в функции.
Мафиозная диктатура это нестабильность. Если не мафиозная диктатура, то Конституция и демократия.
Re[7]: Тестовое задание C++ win
От: andrey.desman  
Дата: 01.12.09 12:53
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Ты не можешь гарантировать то, что delete не переопределён и работает корректно.

А еще я не могу гарантировать, что завтра мне кирпич на голову не упадет
Re[6]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 01.12.09 13:47
Оценка:
Здравствуйте, Kernan, Вы писали:

K>вот только вопрос есть, тебе на вход приходит 0, а на вход функции g ты передёшь 1. Подмена понятий, однако. Хотя код неплох, есть чему поучится


Если ты присмотришься внимательно, то заметишь: на вход g приходит 0.

Но в конструкторы векторов действительно приходит 1. Это нужно затем, чтобы эмулировать поведение new char[0].
Дело в том, что char* p = new char[0] — это валидный ненулевой неразыменовываемый (обрати внимание на эти три слова!) указатель за конец массива.

Вектор же не оперирует указателями. Он отдаёт итераторы, разыменовывая которые, получаем ссылки (*v.begin()); или же сразу ссылки (v[0], v.front()).
Потом ссылку можно восстановить до указателя (&v.front()) и, прибавив размер, получить указатель за конец массива (&v.front()+v.size()).
Итератор конца (v.end()) неразыменовываемый, *v.end() — UB. Так что лобовое решение &*v.end() не подходит.

Соответственно, если вектор нулевого размера, v.begin()==v.end(), получить указатель не получится.

Можно, конечно, набраться наглости и сказать v.resize(0); char*p=&v.front(); — но, повторю, это неопределённое поведение. Например, в отладочной версии STL ест шанс схлопотать assert(false).

Но даже если не будет assertion fault, можем получить p==NULL (раз размер нулевой, то внутренний массив не выделен, а внутренние указатели выставлены в некое дефолтное, т.е. нулевое значение).
То есть, указатель для g() будет валидный, неразыменовываемый (а мы и не собирались разыменовывать — n==0), но — нулевой.

Возможно, что g() способно работать и с набором параметров g(NULL,NULL,0). Этого из начальных условий задачи мы не знаем. Поэтому я и предложил трюк с max(n,1).
Тем более, что нагрузка на кучу для new char[0] и new char[1] (внутри vector) — почти одинаковая.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[8]: Тестовое задание C++ win
От: andrey.desman  
Дата: 01.12.09 16:57
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Получается, что ты предполагаешь, что функция g проверяет n >= 0, чего может и не быть. Более того, неизвестный код может длелать какие-то действия в случае (NULL, NULL, 0).

Может, не может, а вдруг и не так, а сяк. Предположения летят в мусорное ведро. Акстись запускать вот так просто какой-то неизвестный код! Просто смотришь в код функции и видишь что она делает. Или доку читаешь. Или, наконец, просто один раз проверяешь.
Изначальный вопрос — дерьмо, т.к. искать сферические проблемы в сфрическом коде суть занятие бесполезное, потому что проблем можно напридумывать кучу. И спорить кто прав, кто виноват потом можно до усрачки, потому что у одного глаз косит на 30 градусов, а у другого на 17, и никак их точки зрения не совпадут...
А самый главный косяк в изначальном коде — это с особым усердием подобранные, как бы намекающие на всю глупость ситуации, имена функций и переменных. Вот где есть простор для фантазии! Кто какое имя придумает? Устроим знатный holy war!
Re[3]: Тестовое задание C++ win
От: IID Россия  
Дата: 01.12.09 17:26
Оценка:
Здравствуйте, Vamp, Вы писали:

R>>Если вылетит исключение при выделении памяти под b, то память для a не будет освобождена -> утечка память.

V>Ну какая утечка? Если вылетит исключение в приведенном фрагменте, программа просто завершится и всю память почистит ОС.

Почему же ? Окружение, в котором вызывается функция f нам неизвестно. Вполне возможно что там исключение будет перехвачено, и программа нисколько не завершится. Итого: утечка.
kalsarikännit
Re[9]: Тестовое задание C++ win
От: Erop Россия  
Дата: 02.12.09 16:39
Оценка:
Здравствуйте, maykie, Вы писали:

M>Не понял зачем ей это проверять. n всегда >= 0. size_t беззнаковый.

Почему size_t всегда должен быть беззнаковым?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: Тестовое задание C++ win
От: igna Россия  
Дата: 02.12.09 16:48
Оценка:
Здравствуйте, Erop, Вы писали:

E>Почему size_t всегда должен быть беззнаковым?



7.17 Common definitions <stddef.h>

. . .


size_t

which is the unsigned integer type of the result of the sizeof operator

(ISO/IEC 9899:1999)

Re[7]: Тестовое задание C++ win
От: Smal Россия  
Дата: 02.12.09 21:00
Оценка:
Здравствуйте, alexander_st, Вы писали:

_>Здравствуйте, Кодт, Вы писали:


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


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

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

К>>Да вот только что: http://codepad.org/9DrfRKDV

_>Из каких соображений тогда ну скажем ф-я std::string c_str() возвращает const char* а не просто char* ? может для того , что бы показать, что удалять этот буфер не надо?

Нет, для того, чтобы показать что этот буфер изменять не надо.
С уважением, Александр
Re: Тестовое задание C++ win
От: minorlogic Украина  
Дата: 02.12.09 21:18
Оценка:
Здравствуйте, amberovsky, Вы писали:

A>В итоге мне отказали.

A>В чём я ошибся или чего важного не указал?
1.
void g( char *, char *, size_t );
Функция совершенно непонятно что делает? функцию с именем g и без коментария необходимо переписать.

void f( size_t n )
Кроме описанного выше, нет контроля за удалением памяти при возникновении исключения, плюс если нет специальных требований, следует использовать безопасные массивы.

2. Без указания спецификаций непонятно о чем говорить. Использование специальных символов может быть by design, важной фичей.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[8]: Тестовое задание C++ win
От: alexander_st Россия  
Дата: 02.12.09 21:32
Оценка:
Здравствуйте, Smal, Вы писали:

S>Нет, для того, чтобы показать что этот буфер изменять не надо.

из каких соображений? что будет если его изменить?.... точнее чем изменение буфера хуже его удаления?
Re[2]: Тестовое задание C++ win
От: vsb Казахстан  
Дата: 03.12.09 09:40
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>2. Без указания спецификаций непонятно о чем говорить. Использование специальных символов может быть by design, важной фичей.


При использовании %s printf будет пытаться вытаскивать из стека указатели на строки (которые туда никто не клал). Как минимум это UB, и будет печататься мусор, как максимум — в случае более сложной программы можно анализировать стек и вытаскивать какие то, возможно, важные данные.
Re[3]: Тестовое задание C++ win
От: minorlogic Украина  
Дата: 03.12.09 09:47
Оценка:
Повторюсь, что без указания требований совсем непонятно что к чему. Может можно использовать std::cout? или printf тут необходим?
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[8]: Тестовое задание C++ win
От: alexander_st Россия  
Дата: 03.12.09 11:10
Оценка:
Здравствуйте, Кодт, Вы писали:

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


_>>Из каких соображений тогда ну скажем ф-я std::string c_str() возвращает const char* а не просто char* ? может для того , что бы показать, что удалять этот буфер не надо?


К>Знаешь, есть дофига способов abuse. Например, получить указатель на неконстантный объект в стеке или статике — и попробовать его удалить. И никто не пикнет, кроме менеджера кучи перед смертью.

К>Ещё можно попробовать удалить delete[] &vec.front() — вполне себе неконстантный массив, рамещённый на куче... Ты просто украдёшь право владения, которое было у вектора.

К>Язык С++ в явном виде не декларирует права владения указуемыми объектами. Иначе бы указатель на стековый объект и указатель на объект, созданный на куче, должны были быть разного типа!!!

К>Это можно только гигиеной и дисциплиной обеспечить. Гигиена — это, как минимум, умными указателями с политиками.
К>Беда в том, что голый указатель предоставляет сразу все права (ну только с константностью есть ограничение на изменение объекта). А следовательно, всегда остаётся возможность для нецелевого использования. А следовательно — без дисциплины никуда.

это все хорошо и правильно, но увы, даже на 1% не отвечает на мой вопрос
Re[9]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 03.12.09 11:31
Оценка:
Здравствуйте, alexander_st, Вы писали:

_>это все хорошо и правильно, но увы, даже на 1% не отвечает на мой вопрос

Потому что ты упорно задаёшь свой вопрос как риторический.

Буквальный ответ про string: она возвращает указатель на массив из константных элементов, чтобы никто не мог изменять значения этих элементов.

При этом подразумевается, что массивом владеют только объекты string. Какое там владение: монопольное или разделяемое (когда несколько объектов пользуются общим массивом, идиома COW) — для пользователя не имеет значения. НЕ ЕГО СОБАЧЬЕ ДЕЛО.

Это подразумевание запрещает управлять памятью извне. И более того, если программист не враг себе, он не имеет права управлять никакой памятью, которая ему не отдана во владение.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[5]: Тестовое задание C++ win
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 03.12.09 22:00
Оценка:
Здравствуйте, Vamp, Вы писали:

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

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

Да ладно тебе. Две элементарные задачи и ни одного правильного ответа. Почему здесь нужно тщательное обсуждение? Тем более задача решается удалённо, никто никого не торопит.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[7]: Тестовое задание C++ win
От: Head Ache  
Дата: 04.12.09 06:39
Оценка:
Здравствуйте, Vamp, Вы писали:

К>>Незнание законов не освобождает от ответственности. Раз есть new, значит, есть и std::bad_alloc.

V>Где? В вызывающей функции он есть. Но я вообще-то не считаю, что bad_alloc надо перехватывать, за исключением редких стратегий типа — попросим 10 гиг, не получилось — тогда 5, опять не получилось, тогда 2 Кб. Как правило, программа просит столько памяти, сколько ей надо для работы, и ничего осмысленного после bad_alloc сделать не сможет. Более того, в ситуации тотальной нехватки вполне возможно, что даже диагностические сообщения вывести не удастся, так что пусть уж честно рушится. По крайней мере, в тех же Unix будет вполне читабельная корка.

Похоже, ты никогда не видел переопределенного new. Который например, может брать память из какого-нибудь ограниченного по размеру блока, отображенного файла и вообще хз откуда. И даже наличие свободного гига еще совсем не значит, что malloc на гиг будет успешным — фрагментацию пока никто не отменял! Нет никакой гарантии, что ОС справится с фрагментацией!
И даже при стандартном new в ответ на bad_alloc еще много чего можно сделать. Например, если не получилось выполнить текущую задачу в списке — можно просто ее не выполнить и перейти к следующей.
Этот аккаунт покинут.
Re[2]: Тестовое задание C++ win
От: Head Ache  
Дата: 04.12.09 06:43
Оценка:
Здравствуйте, McSeem2, Вы писали:

MS>Не вижу ни малейшей проблемы в этом примере. Точнее сказать так — все зависит от контекста применения. А контекста нету. Бывают, например, случаи, когда исключения вообще запрещены. И если new может венуть 0, а в g() это обрабатывается, то даный код полностью легален.


А такой new так же пишется?
Насколько можно понять, тест на знание _современного_ С++?
Этот аккаунт покинут.
Re: Тестовое задание C++ win
От: Rothmans  
Дата: 09.12.09 11:48
Оценка:
Re: Тестовое задание C++ win
От: duncanmclaud  
Дата: 24.12.09 14:04
Оценка:
Здравствуйте, amberovsky, Вы писали:

A>Здравствуйте.

A>При попытке устроится в одну фирму прислали "удалённое" тестовое задание.



A>
A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}

A>2.
A>int main(int argc, char* argv[])
A>{
A> if( argc > 1 )
A>  printf( argv[1] );
A> return 0;
A>}

A>


A>Я ответил так:

A>1. new может не сработать, нужно добавить, например, try/catch. Кроме того, g может "испортить" указатели (как тут просто решить я не знаю)
A>2. В аргументе командной строки может встретиться символ % или \, что будет расценено printf как специальный символ.
A>Если следующие символы совпадут с какой-либо спецификацией формата (для % или \), то в данном случае для % — UB, для \ — произойдёт подстановка.
A>Решение — printf("%s", argv[1]);
A>Ещё можно проверить что printf действительно напечатало нужное количество символов.


A>В итоге мне отказали.

A>В чём я ошибся или чего важного не указал?



void g( char *, char *, size_t)
{
}

void f( size_t n )
{
char *a = new(nothrow) char[n];
char *b = new(nothrow) char[-n];// если не возможно выделить память, как в данном случае, не генерит эксепшн, просто возвращает 0.

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

if(b)
{
delete [] b;
b = 0;
}

if(a)
{
delete [] a;
a = 0;
}
}
Re: Тестовое задание C++ win
От: duncanmclaud  
Дата: 24.12.09 14:07
Оценка:
Здравствуйте, amberovsky, Вы писали:

A>Здравствуйте.

A>При попытке устроится в одну фирму прислали "удалённое" тестовое задание.



A>
A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}

A>2.
A>int main(int argc, char* argv[])
A>{
A> if( argc > 1 )
A>  printf( argv[1] );
A> return 0;
A>}

A>


A>Я ответил так:

A>1. new может не сработать, нужно добавить, например, try/catch. Кроме того, g может "испортить" указатели (как тут просто решить я не знаю)
A>2. В аргументе командной строки может встретиться символ % или \, что будет расценено printf как специальный символ.
A>Если следующие символы совпадут с какой-либо спецификацией формата (для % или \), то в данном случае для % — UB, для \ — произойдёт подстановка.
A>Решение — printf("%s", argv[1]);
A>Ещё можно проверить что printf действительно напечатало нужное количество символов.


A>В итоге мне отказали.

A>В чём я ошибся или чего важного не указал?


void g( char *, char *, size_t)
{
}

void f( size_t n )
{
char *a = new(nothrow) char[n];
char *b = new(nothrow) char[-n]; // если память не возможно выделить, как в данном случае, эксепшена не будет, возвратится 0

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

if(b)
{
delete [] b;
b = 0;
}

if(a)
{
delete [] a;
a = 0;
}
}
Re[7]: Тестовое задание C++ win
От: Roman Odaisky Украина  
Дата: 26.12.09 18:53
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Дело не в экспорте, а в языке. Зачем С++ функции принимать указатели, если можно векторы?


Было — void g(char *, std::size_t).

Стало — void g(std::vector<char, а здесь что?> &).
До последнего не верил в пирамиду Лебедева.
Re[6]: Тестовое задание C++ win
От: Zhendos  
Дата: 13.01.10 12:30
Оценка:
Здравствуйте, KoriBRand, Вы писали:

KBR>Здравствуйте, SergeyT., Вы писали:


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


S>>>>Ну, тогда уж

S>>>>
S>>>>void f( size_t n )
S>>>>{
S>>>> std::vector<char> a (n);
S>>>> std::vector<char> b (n);
S>>>> g( &a[0], &b[0], n );
S>>>>}
S>>>>


ST>>Это не очень красивая, но совершенно стандартная идиома.

ST>>Скотт Мейерс, Эффективное использование STL, Item 16

KBR>Ну нахрен такие идиомы. Добавишь ты в вектор новый элемент, сделает он реаллокацию внутреннего буфера, и указатель, который передавался в doSomething станет невалидным.


вообще-то данный пример изначально выглядел как

p = new
doSomething
delete p


если doSomething сохраняет и при повторных вызовах его использует, то будет такая же проблема
что и с vector,
в чем смысл вашего возражения?
Re: Тестовое задание C++ win
От: KhConstantine Россия  
Дата: 02.05.10 14:47
Оценка:
Здравствуйте, amberovsky, Вы писали:

A>Здравствуйте.

A>При попытке устроится в одну фирму прислали "удалённое" тестовое задание.
Мне пришло такое задание от DrWeb. Кто-то еще так развлекается?
В общем, побывал я в DrWeb на собеседовании и даю правильный с их точки зрения ответ:
По первому заданию:

void f_drWeb( size_t n )
{
     using namespace std;
     vector<char> a (n), b(n);
     g( &a[0], &b[0], n );
     cout<<endl<<"func f_drWeb said:"<<"a="<<&a[0]<<" b="<<&b[0];
};



По второму заданию:



int main(int argc, char* argv[])
{
    const char *locId="Russian";
    // Для C
    if(argc>1)
    {
        printf("\n printf said: %s", argv[1]);
        setlocale(LC_ALL, "Russian"); // "Russian" - для винды и русского. Это необходимо для C, 
                                      // но недостаточно для wcout
    }      

    //Для потоков
    locale loc(locId);
      locale::global(loc); // Это необходимо для wcout(setlocale недостаточно).
    wcout.imbue(loc);    // Применяем к wcout, потому что wcout УЖЕ открыт. Действует и на stdout
                         // так что в принципе можно обойтись и без setlocale
    if(argc>1)
    {
        wcout<<endl<<"wcout said:"<<argv[1];
    };
return 0;
}



A>
A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}

A>2.
A>int main(int argc, char* argv[])
A>{
A> if( argc > 1 )
A>  printf( argv[1] );
A> return 0;
A>}

A>



Кроме того, можете скачать http://piterludi.com/fordeveloponbox/stlfuns.zip
В этом проекте (VC++ 2008) я продемонстрировал также поведение виртуальных функций, вызываемых из конструкторов и деструкторов — вопрос,
который почему-то нередко возникает на собеседованиях. Также немного побаловался с промышленным дизайном для этой же задачи.
Хотя по ходу собеседования я и сделал вывод, что промышленный дизайн и общепринятые подходы они считают
ненужным усложнением и ретроградством.

Возможно, я ошибаюсь: все-таки собеседование проходило в стиле "опусти кандидата",
а при таком стиле язвительно критикуется любое высказывание.
Вероятно, предполагается, что осознавший свое ничтожество и полностью дезориентированный кандидат
преисполнится безумной радости, если ему все-таки сделают предложение поработать в такой новаторской фирме.
Просто держите в голове, что "опустить" можно любого: конкретно моих "экзаменаторов" можно было бы легко "опустить" как минимум
по знаниям паттернов проектирования (особенно сoncurrency) и подходам к разработке сложных систем. Никто не может знать всего.

Если будете у них на собеседовании — в момент, когда от вас потребуют что-либо написать, постарайтесь не отвлекаться
на вопросы "экзаменаторов", "заторапливание" и попытки вывести вас из себя. Иначе наделаете таких ляпов, что самому потом будет стыдно.
Re[2]: Тестовое задание C++ win
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 02.05.10 14:57
Оценка:
Здравствуйте, KhConstantine, Вы писали:

KC> я продемонстрировал также поведение виртуальных функций, вызываемых из конструкторов и деструкторов — вопрос,

KC>который почему-то нередко возникает на собеседованиях.

Больная тема, наверное....

К примеру — в последнее время мой IE8 стал слишком часто говорить "pure virtual что-то там call"
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[3]: Тестовое задание C++ win
От: KhConstantine Россия  
Дата: 02.05.10 17:42
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>К примеру — в последнее время мой IE8 стал слишком часто говорить "pure virtual что-то там call"

Очень интересно... Потому что именно MSVC вроде бы матерится на это на этапе ЛИНКОВКИ, а не рантайма...
Мне тоже на одном из собеседований утверждали, что маты идут на этапе рантайма, причем с именно MS.
Интересно было бы пример посмотреть — в реальной жизни я с таким не встречался.
А вот в архиве, на который я сделал ссылку,этот кусочек — как раз на линковке валится:

stlfuns_main.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AGFuncCaller::dump(void)" (?dump@AGFuncCaller@@UAEXXZ)
D:\experiments\stlfuns\Debug\stlfuns.exe : fatal error LNK1120: 1 unresolved externals

// базовый для всех объектов, работающих с G
// в том числе и для тех, которым данные из буфера нужны
class AGFuncCaller
{    
........        
            
        AGFuncCaller(SomeSubSystem &oSomeSubSystem)
        {
            //dump(); // uncomment it to see the LINKER (not real-time) problem of calling 
                    //abstract virtual function
            gBufferSize     = 0;                    
            _oSomeSubSystem = &oSomeSubSystem;
            getSubSystem()->log("1. Constructor AGFuncCaller said:");
            someVirtualFunc();
            getSubSystem()->log("1. Constructor AGFuncCaller finishing");
        };

......        
        virtual void dump()=0;
......
};
Re[4]: Тестовое задание C++ win
От: Alexey F  
Дата: 02.05.10 18:42
Оценка:
Здравствуйте, KhConstantine, Вы писали:

КД>>К примеру — в последнее время мой IE8 стал слишком часто говорить "pure virtual что-то там call"

KC>Очень интересно... Потому что именно MSVC вроде бы матерится на это на этапе ЛИНКОВКИ, а не рантайма...
KC>Мне тоже на одном из собеседований утверждали, что маты идут на этапе рантайма, причем с именно MS.
KC>Интересно было бы пример посмотреть — в реальной жизни я с таким не встречался.
KC> А вот в архиве, на который я сделал ссылку,этот кусочек — как раз на линковке валится:

А так? (MS VC под рукой нет, поэтому GCC; через промежуточную функцию ):
class Base {
public:
    Base () {
        anotherFunction ();
    }
    
    
    void anotherFunction () {
        pure ();
    }
    
    
    virtual void pure () = 0;
};


class Derived : public Base {
public:
    virtual void pure () {
        return;
    }
};


int main () {
    Derived derived;
}


Результат:

pure virtual method called
terminate called without an active exception

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Re[4]: Тестовое задание C++ win
От: Вертер  
Дата: 02.05.10 20:10
Оценка:
КД>>К примеру — в последнее время мой IE8 стал слишком часто говорить "pure virtual что-то там call"
KC>Очень интересно... Потому что именно MSVC вроде бы матерится на это на этапе ЛИНКОВКИ, а не рантайма...

везёт же некоторым , а вот кто работал с Visual Studio 6.0 знает, что компилятор гордо промолчит и даже никакого warning не будет на 4м уровне.

Во всех последующих версиях студии, генерится ошибка на этапе компиляции.
Re[9]: Тестовое задание C++ win
От: Юрий Жмеренецкий ICQ 380412032
Дата: 03.05.10 05:37
Оценка:
Здравствуйте, Кодт, Вы писали:

К>boost::scoped_array — более предпочтительный вариант в этом плане.


В C++0x можно обойтись без буста: 'std::unique_ptr<char[]>'.
Re[5]: Тестовое задание C++ win
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 03.05.10 11:07
Оценка:
Здравствуйте, Вертер, Вы писали:

КД>>>К примеру — в последнее время мой IE8 стал слишком часто говорить "pure virtual что-то там call"


В>везёт же некоторым , а вот кто работал с Visual Studio 6.0 знает, что компилятор гордо промолчит и даже никакого warning не будет на 4м уровне.


Навеяло:
— "Предлагаю сразу перейти к третьей степени устрашения. У нас даже генералы плачут как дети."
— "Разрешите присутствовать?!"

Шматрица.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[4]: Тестовое задание C++ win
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 03.05.10 11:27
Оценка:
Здравствуйте, KhConstantine, Вы писали:

КД>>К примеру — в последнее время мой IE8 стал слишком часто говорить "pure virtual что-то там call"

KC>Очень интересно... Потому что именно MSVC вроде бы матерится на это на этапе ЛИНКОВКИ, а не рантайма...

здесь
Автор: Коваленко Дмитрий
Дата: 05.05.06
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[5]: Тестовое задание C++ win
От: slava_phirsov Россия  
Дата: 04.05.10 06:24
Оценка:
Здравствуйте, Alexey F, Вы писали:

AF>А так? (MS VC под рукой нет, поэтому GCC; через промежуточную функцию ):

AF>
AF>class Base {
AF>public:
AF>    Base () {
AF>        anotherFunction ();
AF>    }
    
    
AF>    void anotherFunction () {
AF>        pure ();
AF>    }
    
    
AF>    virtual void pure () = 0;
AF>};


AF>class Derived : public Base {
AF>public:
AF>    virtual void pure () {
AF>        return;
AF>    }
AF>};


AF>int main () {
AF>    Derived derived;
AF>}
AF>


Давно известно, что вызов виртуальной функции в конструкторе в C++ — А-ТА-ТА, в отличие, кстати, от ныне полупокойной Delphi. Еще одна веревка для отстрела собственных конечностей, которых в C++, увы (ура?) хватает.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[5]: Тестовое задание C++ win
От: March_rabbit  
Дата: 04.05.10 08:13
Оценка:
Здравствуйте, igna, Вы писали:

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


K>>Соглашусь. В catch delete лучше убрать.


I>catch, который ловит что попало и это "что попало" затем не перебрасывает, тоже лучше убрать.

здесь у catch есть одна задача: остановить бабах и дать возможность процедуре восстановиться после него.
Так что, пусть постоит....
Re: Тестовое задание C++ win
От: March_rabbit  
Дата: 04.05.10 08:19
Оценка:
Здравствуйте, amberovsky, Вы писали:

A>Я ответил так:

A>1. new может не сработать, нужно добавить, например, try/catch.
Думаю, чисто теоретически это все правильно. Но на практике я бы не сильно заморачивался спецзащитой. Ибо нехватка памяти — это конец. Поймаешь здесь — стрельнет в другом месте (где-нить в stdlib).

За 10 лет программерства ни разу не столкнулся с нехваткой памяти под программу на i386. Один раз сделал утечку, система (Linux) умерла в муках, но не призналась.
Re[2]: Тестовое задание C++ win
От: IROV..  
Дата: 04.05.10 22:27
Оценка:
Здравствуйте, Кодт, Вы писали:

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


A>>1. new может не сработать, нужно добавить, например, try/catch.

К>Лучше не try-catch (это слишком громоздко), а RAII — любой умный указатель или контейнер.
Который будет врапером над try-catch?

A>> Кроме того, g может "испортить" указатели (как тут просто решить я не знаю)

К>Паранойя. Чтобы испортить указатели, функция должна расстрелять стек. А это никакими средствами не лечится.
К>А вот метнуть исключение функция g() может запросто.
А еще сигнатура функции может принимать ссылку на указатель и творить с ним все что захочет
я не волшебник, я только учусь!
Re[3]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 05.05.10 11:11
Оценка:
Здравствуйте, IROV.., Вы писали:

A>>>1. new может не сработать, нужно добавить, например, try/catch.

К>>Лучше не try-catch (это слишком громоздко), а RAII — любой умный указатель или контейнер.
IRO>Который будет врапером над try-catch?

Нет, RAII — это враппер над try-finally.

IRO>А еще сигнатура функции может принимать ссылку на указатель и творить с ним все что захочет


Ай, шайтан!
Только у нас сигнатура уже прописана, и там указатели передаются по значению.
Перекуём баги на фичи!
Re[4]: Тестовое задание C++ win
От: IROV..  
Дата: 05.05.10 11:19
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Нет, RAII — это враппер над try-finally.

Это чемто концептуально отличаеться от try-catch?
всегда пологал что try-finally это синтаксический сахар


К>Ай, шайтан!

К>Только у нас сигнатура уже прописана, и там указатели передаются по значению.
От , не заметил обьявление.
я не волшебник, я только учусь!
Re[5]: Тестовое задание C++ win
От: Кодт Россия  
Дата: 05.05.10 12:16
Оценка:
Здравствуйте, IROV.., Вы писали:

К>>Нет, RAII — это враппер над try-finally.

IRO>Это чемто концептуально отличаеться от try-catch?
IRO>всегда пологал что try-finally это синтаксический сахар
IRO>

Они все — синтаксический сахар над longjmp.

Разница в том, что try-except пасёт исключения, а try-finally — пасёт любой исход.
Поэтому, если убирать мусор с помощью try-except, это будет дублирование кода или макароны
__try
{
  Take();
  .....
  .....
  Give();
}
__except(1)
{
  Give();
  RaiseException(.....); // повторно бросаем
}

//////////////

__try
{
  Take();
  .....
  .....
}
__finally
{
  Give();
}
Перекуём баги на фичи!
Re[6]: Тестовое задание C++ win
От: IROV..  
Дата: 05.05.10 14:20
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Разница в том, что try-except пасёт исключения, а try-finally — пасёт любой исход.

Ну я как бы в курсе дела, Док.

К>Поэтому, если убирать мусор с помощью try-except, это будет дублирование кода или макароны

Поэтому я и люблю такого рода синтаксический сахар но С++ извольте не дает такой возможности.
конечно можно воспользоваться запрещеным приемом и сворганить чтото типа вот этого try-finally
Автор(ы): Проскурня М.О.
Дата: 19.03.2004
В некоторых языках программирования существует конструкция вида try-finally, в которой секция finally выполнялась обязательно, как при возникновении исключений, так и при нормальном ходе выполнения программы. Поскольку в языке C++ такой конструкции явно не присутствует, мы можем попытаться описать её самостоятельно, прибегая к помощи макропрепроцессора.
я не волшебник, я только учусь!
Re[2]: Тестовое задание C++ win
От: TarasKo Голландия  
Дата: 05.05.10 17:06
Оценка:
ИХМО без обоснования, изобретать подсистемы, и интерфесы по типу AGFuncCaller нет никакого смысла, в том числе и промышленных программах, и кстати понятие "промышленный дизайн" вообще осталось для меня не ясным. Для вас "промышленный дизайн", это наличие интерфейса SomeSubSystem и интерфейсов по типу AGFuncCaller?

А код у вас аккуратный, и в хорошем стиле, читается легко и приятно , комментарии ещё б были к функциям и классам в doxygen-е и было б идеально.
Re[3]: Тестовое задание C++ win
От: KhConstantine Россия  
Дата: 05.05.10 17:53
Оценка:
Здравствуйте, TarasKo, Вы писали:

TK>ИХМО без обоснования, изобретать подсистемы, и интерфесы по типу AGFuncCaller нет никакого смысла, в том числе и промышленных программах, и кстати понятие "промышленный дизайн" вообще осталось для меня не ясным. Для вас "промышленный дизайн", это наличие интерфейса SomeSubSystem и интерфейсов по типу AGFuncCaller?

Вы правы, конечно. ВЕСЬ этот код — одно сплошное баловство. Написанное просто так, без веской причины. Дизайн создается под конкретную цель.
Здесь — вообще никакой цели. Говоря о "промышленном дизайне" всего-навсего имел в виду, что есть и подходы, целесообразные для небольших задач (которые можно написать в одиночку за разумное время), либо "одноразовых". А то, что для мелких задач является избыточно сложным, становится экономически выгодным на крупных задачах, которые живут долго — и постоянно модифицируются, да притом и разными людьми.

TK>А код у вас аккуратный, и в хорошем стиле, читается легко и приятно , комментарии ещё б были к функциям и классам в doxygen-е и было б идеально.

На это меня уже не хватило .
Re[3]: Тестовое задание C++ win
От: alxn1 Россия  
Дата: 05.05.10 18:54
Оценка:
Офигеть. Сколько негатива и неуважения. Даже "Вы" выглядит издевкой.

Ждем и правда вашего кода.
Re[5]: Тестовое задание C++ win
От: KhConstantine Россия  
Дата: 05.05.10 19:43
Оценка:
AF>А так? (MS VC под рукой нет, поэтому GCC; через промежуточную функцию ):

А вот так — я в MSVC 2008 увидел ошибку в рантайм, а линковка ничего не заметила.
Спасибо!
Re: Тестовое задание C++ win
От: sergey_cheban  
Дата: 06.05.10 09:29
Оценка:
Здравствуйте, amberovsky, Вы писали:

A>При попытке устроится в одну фирму прислали "удалённое" тестовое задание.

Раз уж это задание попало на RSDN и стало предметом обсуждения, позвольте несколько комментариев от автора.

1. Целью этого задания является предварительный отсев кандидатов. Если кандидат нормально ответил на вопросы, мы приглашаем его на собеседование. Как показывает практика, на этом этапе отсеивается примерно половина кандидатов, что серьёзно экономит наше время.
2. Основным требованием к заданию является простота его выполнения (для тех кандидатов, которые нам подходят). Сложные задания отпугивают кандидатов, а нам это не нужно.
3. Никаких "единственно правильных ответов" не существует. Ответы рассматривают разработчики, а не отдел кадров. На этом этапе мы готовы принять любой вариант, который решает больше проблем, чем создаёт.
4. Мы тоже иногда ошибаемся, причём при наличии сомнений предпочитаем отказать кандидату. В конце концов, каждый ошибочно принятый на работу человек обходится нам в несколько десятков тысяч рублей чистого убытка, а каждый ошибочно отвергнутый — найдёт себе применение где-нибудь в другом месте.
5. Если кандидат в процессе чтения этой ветки узнаёт много нового и интересного для себя — это верный признак того, что ему ещё есть чему поучиться до того, как он сможет претендовать на работу у нас.
Re[2]: Тестовое задание C++ win
От: los puercos  
Дата: 06.05.10 09:59
Оценка:
Здравствуйте, March_rabbit, Вы писали:

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


A>>Я ответил так:

A>>1. new может не сработать, нужно добавить, например, try/catch.
M_>Думаю, чисто теоретически это все правильно. Но на практике я бы не сильно заморачивался спецзащитой. Ибо нехватка памяти — это конец. Поймаешь здесь — стрельнет в другом месте (где-нить в stdlib).

M_>За 10 лет программерства ни разу не столкнулся с нехваткой памяти под программу на i386. Один раз сделал утечку, система (Linux) умерла в муках, но не призналась.


Это не так. Есть ситуации когда ловля bad_alloc спасает ситуацию.
Например при попытке выделить огромный объем памяти ее может не хватить — не рушить же из-за этого программу. Можно поймать bad_alloc и например попробовать выделить поменьше.
Если программа работает в критичном окружении (сервер, обрабатывающий тысячи запросов), на очередную операцию может запросто не хватить ресурсов. Рушить сервер в данном случе в корне неверно — нужно наоборот предпринять усилия спасти его, например перестать принимать запросы пока не освободиться память.

На практике тоже не сталкивался, но генерил такую ситуацию (Vista 32 bit, 3 Gb RAM) — ислючение отработало, винда выдержала.
Re[4]: Тестовое задание C++ win
От: sergey_cheban  
Дата: 06.05.10 12:38
Оценка:
Здравствуйте, alxn1, Вы писали:

A>Офигеть. Сколько негатива и неуважения. Даже "Вы" выглядит издевкой.

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

A>Ждем и правда вашего кода.

Зачем? В данном случае оценка моей квалификации зависит не от моего умения писать код, а от того, правильно ли я оценил кандидата. Если Вы считаете, что я ошибся — пожалуйста, берите его себе.

Надеюсь, Вы чувствуете границу между защитой чести и достоинства и самоутверждением. Я эту границу переходить не хочу.
Re[4]: Тестовое задание C++ win
От: sergey_cheban  
Дата: 06.05.10 14:54
Оценка:
Здравствуйте, KhConstantine, Вы писали:

KC> Покажите нам, КАК ВЫ САМИ пишете серьезные приложения — отнюдь не тексты под копирайтом,

KC>о нет! И никто вас не просит выложить нечто, что требует больше нескольких часов работы.
Вы предлагаете мне быстренько, на коленке, за пару часов написать "серьёзное приложение"?
Или Вы предлагаете написать что-нибудь простенькое, но использовать при этом избыточно "тяжёлый" подход?

KC>Дайте же нам идеал, к которому нам надлежит стремиться!

Отстаньте, нет у меня этого идеала. И нимба вокруг головы — тоже нет.

KC> Вы же сами критики не боитесь?

Вам угодно считать меня плохим программистом? Ради бога. Главное — не ставьте мои копирайты на свой код и воздержитесь от описаний моего мнения.
Вам угодно заняться фаллометрией на форуме? С этим — не ко мне.
Re[3]: Тестовое задание C++ win
От: yuriylsh  
Дата: 07.05.10 04:40
Оценка:
Здравствуйте, KhConstantine, Вы писали:
KC>[skip]

Я бы посоветовал тебе расслабиться и прислушаться к написанному тут
Автор: TarasKo
Дата: 06.05.10
.
Luck in life always exists in the form of an abstract class that cannot be instantiated directly and needs to be inherited by hard work and dedication.
Re[5]: Тестовое задание C++ win
От: KhConstantine Россия  
Дата: 07.05.10 04:44
Оценка:
Здравствуйте, TarasKo, Вы писали:

TK>Советую забить У меня тоже бывали случаи, когда после собеседования хотелось кричать и махать кулаками, мне казалось что со мной поступили не справедливо, я тоже писал на рсдн например здесь

TK>http://www.rsdn.ru/forum/philosophy/2971148.aspx
Автор: TarasKo
Дата: 30.05.08


TK>Теперь я по другому к этому отношусь. Конечно собеседующие могут быть не идеальны, но эта та часть мира которую мне не изменить. Зато я могу изменить себя. Могу читать больше книжек, могу учиться разговаривать по другому, так что бы не возникало желания меня гнобить Вспоминая то собеседование, могу сказать что я был очень самоуверен, вел себя соответствующе, быстро и слишком подробно ответил на вводные вопросы про с++, мне иногда казалось, что собеседующий меня не понимает. Видимо этим его разозлил


TK>Собеседование это ж не только проверка на знание, но и проверка насколько я коммуникабелен. Если так получилось что за время собеседование я разозлил интервьюера, то это тоже повод задуматься. Меня не возьмут на работу даже если я буду ВСЁ знать, ведь как потом со мной работать.


TK>Вообщем я из того случая надеюсь извлёк свои уроки Вам сооветую сделать тоже самое и не на кого не злится

У меня с коммуникабельностью все в порядке, спасибо. Выводы тоже давно сделал. В частности, пришел к выводу, что если на собеседовании возможные коллеги из числа "равных" не могут вытерпеть отношение "равный к равному" — потом тем более не смогут. Думаю, что ставить себя в позу "послушный мальчик" на собеседовании имеет смысл только в особых случаях.
А вот предела совершенству в профессиональной сфере — действительно нет.
Re[5]: Тестовое задание C++ win
От: KhConstantine Россия  
Дата: 07.05.10 04:58
Оценка:
Здравствуйте, sergey_cheban, Вы писали:

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


A>>Офигеть. Сколько негатива и неуважения. Даже "Вы" выглядит издевкой.

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

A>>Ждем и правда вашего кода.

_>Зачем? В данном случае оценка моей квалификации зависит не от моего умения писать код, а от того, правильно ли я оценил кандидата. Если Вы считаете, что я ошибся — пожалуйста, берите его себе.

_>Надеюсь, Вы чувствуете границу между защитой чести и достоинства и самоутверждением. Я эту границу переходить не хочу.


По-моему, Вам не помешает познакомиться с работами Эрика Берна и книжкой русского автора "Игры, в которые играют менеджеры" (автора не помню). Если еще не знакомы, конечно. Ну а негатив и неуважение никогда полезными не бывают.
Оптимальный стиль общения — нейтрально-положительный. Безэмоциональная формулировка решения, опционально — причин решения.
Re[5]: Тестовое задание C++ win
От: KhConstantine Россия  
Дата: 07.05.10 06:49
Оценка:
Здравствуйте, sergey_cheban, Вы писали:

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


KC>> Покажите нам, КАК ВЫ САМИ пишете серьезные приложения — отнюдь не тексты под копирайтом,

KC>>о нет! И никто вас не просит выложить нечто, что требует больше нескольких часов работы.
_>Вы предлагаете мне быстренько, на коленке, за пару часов написать "серьёзное приложение"?
_>Или Вы предлагаете написать что-нибудь простенькое, но использовать при этом избыточно "тяжёлый" подход?
Именно простенькое, "на коленке", но с "тяжелым" подходом. Если под словом "тяжелый" вы понимаете те подходы, что следует применять
при коллективной разработке сложных систем по вашему мнению.

И не бойтесь, что я отнесусь к нему так же, как вы отнеслись к моему написанному на коленке за пару часов коду.
У меня вообще нет привычки "опускать" собеседников, тем более — распуская пальцы веером над приложением, которое нет смысла вылизывать и документировать. А то, что в любом коде, написанном "на автомате" и не отсмотренном повторно коде ляпы будут, и много — очевидно.
Более того, и в повторно отсмотренном самим программистом коде встречаются ляпы, ибо глаз замыливается. Потому во многих конторах еще и
коллективный анализ каждого изменения выполняется. Так что по вашим ляпам от оскорбительных комментариев я воздержусь.

Мне просто интересно — а вдруг я действительно увижу нечто новое для себя?

KC>>Дайте же нам идеал, к которому нам надлежит стремиться!

_>Отстаньте, нет у меня этого идеала. И нимба вокруг головы — тоже нет.

KC>> Вы же сами критики не боитесь?

_>Вам угодно считать меня плохим программистом? Ради бога. Главное — не ставьте мои копирайты на свой код и воздержитесь от описаний моего мнения.
_>Вам угодно заняться фаллометрией на форуме? С этим — не ко мне.

Пока что есть основания считать вас лишь критиком, причем худшего сорта.
И мне совершенно все равно, лучше вы меня как программиста или хуже. Вы не тот эталон, с которым имеет себя сравнивать.
Re[2]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 07.05.10 18:19
Оценка:
_>4. Мы тоже иногда ошибаемся, причём при наличии сомнений предпочитаем отказать кандидату. В конце концов, каждый ошибочно принятый на работу человек обходится нам в несколько десятков тысяч рублей чистого убытка, а каждый ошибочно отвергнутый — найдёт себе применение где-нибудь в другом месте.
Странно, что вы не понимаете, что ошибочно отвергнутый на самом деле обходится в сотни тысяч рублей убытка.
Да здравствует мыло душистое и веревка пушистая.
Re: Тестовое задание C++ win
От: Timur_SPB Россия  
Дата: 08.05.10 21:53
Оценка:
A>
A>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
A>1.
A>void g( char *, char *, size_t );
A>void f( size_t n )
A>{
A> char *a = new char[n];
A> char *b = new char[n];
A> g( a, b, n );
A> delete [] b;
A> delete [] a;
A>}

A>2.
A>int main(int argc, char* argv[])
A>{
A> if( argc > 1 )
A>  printf( argv[1] );
A> return 0;
A>}

A>


Основная проблема — необходимость переписать этот код полностью. А так он нормальный.
Re[4]: Тестовое задание C++ win
От: mike_rs Россия  
Дата: 11.05.10 07:47
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Здравствуйте, 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, такой код трудно сопровождать.

K>Соглашусь. В catch delete лучше убрать.

тогда зачем вообще нужен блок try\catch ?
Re[6]: Тестовое задание C++ win
От: lennyn  
Дата: 26.08.11 12:50
Оценка:
UP!!!
Во, блин. Мне тож drWeb говнокод прислал, даже и не знаю чего им ответить.

Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?
1.
void g( char *, char *, size_t );
void f( size_t n )
{
char *a = new char[n];
char *b = new char[n];
g( a, b, n );
delete [] b;
delete [] a;
}

2.
int main(int argc, char* argv[])
{
if( argc > 1 )
printf( argv[1] );
return 0;
}
*чет глаз дергается*
Re[7]: Тестовое задание C++ win
От: lennyn  
Дата: 26.08.11 12:51
Оценка:
Вроде два года уже прошло.
*чет глаз дергается*
Re[3]: Тестовое задание C++ win
От: 11molniev  
Дата: 26.08.11 14:07
Оценка:
Здравствуйте, Tesh, Вы писали:

T>Здравствуйте, любой, Вы писали:


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


Л>>Тут по существу уже сказали. А меня в таком коде всегда прикалывает, почему два блока нельзя за раз выделить:


Л>>char *a = new char[n*2];

Л>>char *b = a + n;
Л>>g( a, b, n );
Л>>delete [] a;

T>Насколько я понимаю в этом случае нужен будет в два раза больший непрерывный блок памяти, который найти меньше шансов, чем два поменьше

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

Зато операция выделения/освобождения — одна. Что без шансов в ~два раза быстрей & меньше фрагментация памяти. Единственный минус — надо быть внимательней самому и тем кто этот код будет править.
Re[8]: Тестовое задание C++ win
От: lennyn  
Дата: 26.08.11 19:50
Оценка:
На первый вопрос ответил, что текст не отформатирован, переменные и названия функций не несут смысловой нагрузки. Я не должен делать предположения по поводу тела функции g и поведению операторов new, без большей информации нет смысла искать проблемы. На второй ответил, что следуют заменить printf(argv[1]) на puts(argv[1]). Может они хотели услышать про уязвимость printf или еще чего. На досуге подумаю. Смысл в этом задании ведь должен какой-то быть.
*чет глаз дергается*
Re[2]: Тестовое задание C++ win
От: vpchelko  
Дата: 16.01.12 16:08
Оценка:
По поводу такие оптимизацый — http://lurkmore.to/%D0%95%D0%B1%D0%B0%D0%BB_%D0%B5%D1%91_%D1%80%D1%83%D0%BA%D0%B0
Сало Украине, Героям Сала
Re[7]: Тестовое задание C++ win
От: artkarma  
Дата: 17.01.12 08:59
Оценка:
Здравствуйте, lennyn, Вы писали:

L>UP!!!

L>Во, блин. Мне тож drWeb говнокод прислал, даже и не знаю чего им ответить.

L>Какие проблемы Вы видите в этих фрагментах кода и как предлагаете их решать?

L>1.
L>void g( char *, char *, size_t );
L>void f( size_t n )
L>{
L>char *a = new char[n];
L>char *b = new char[n];
L>g( a, b, n );
L>delete [] b;
L>delete [] a;
L>}

L>2.

L>int main(int argc, char* argv[])
L>{
L>if( argc > 1 )
L>printf( argv[1] );
L>return 0;
L>}

Ну раз это доктор Вэб, то
1. Я бы ответил что в функции f n не проверяеться размер n ,можно запросить столько памяти что не сможет выделить система
2. Стопудово что размер argv[1] не проверяеться, программа становиться уязвимой
Re[8]: Тестовое задание C++ win
От: Michael7 Россия  
Дата: 17.01.12 09:38
Оценка:
Здравствуйте, artkarma, Вы писали:


A>Ну раз это доктор Вэб, то

A>1. Я бы ответил что в функции f n не проверяеться размер n ,можно запросить столько памяти что не сможет выделить система

А если задача работать быстро, размер n заведомо не превосходит доступной памяти, а лишние проверки только затормозят?

A>2. Стопудово что размер argv[1] не проверяеться, программа становиться уязвимой


Тогда еще надо проверять и все возможные модификаторы в строке ввода, вообще есть готовые функции для разбора опций, чтобы велосипед не изобретать. А тут может быть программа — это затычка для какого-нибудь скрипта и говорить про уязвимость бессмысленно.

В общем, как я уже написал, на практике без дополнительных не видно смысла что-то с этим делать, тест, строго говоря, некорректный.
Re[9]: Тестовое задание C++ win
От: sergey_cheban  
Дата: 17.01.12 13:05
Оценка:
M>В общем, как я уже написал, на практике без дополнительных не видно смысла что-то с этим делать, тест, строго говоря, некорректный.
А представьте, каково нам. Мы решаем задачу, для которой математически строго доказана невозможность корректного решения: определяем, является ли файл вирусом. Ничего, как-то справляемся.
Re[9]: Тестовое задание C++ win
От: Vain Россия google.ru
Дата: 17.01.12 18:16
Оценка:
Здравствуйте, alexander_st, Вы писали:

S>>Нет, для того, чтобы показать что этот буфер изменять не надо.

_>из каких соображений? что будет если его изменить?.... точнее чем изменение буфера хуже его удаления?
Тем что его уже может не существовать в момент изменения, что может повлеч расстрел памяти с продолжением работы. А вот освобождение не выделенной памяти с высокой вероятностью бужет пресечено сразу же.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[7]: Тестовое задание C++ win
От: Erop Россия  
Дата: 18.01.12 08:59
Оценка:
Здравствуйте, SaZ, Вы писали:


SaZ>Признаю, что возможно немного погорячился с оценкой. Цепляться в этом случае или нет, так сказать, человеко-зависимо. Мои преподаватели бы зацепились (на собеседовании, а на экзамене — тем более).


Это очень от целей собеседования/экзамена зависит...

Но, в любом случае, в ответе всякую ересь можно был бы и не писать...

Кстати, проблема может быть и в том, что вообще используется функция fprintf, а не std::cout, например
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Тестовое задание C++ win
От: TimurSPB Интернет  
Дата: 18.01.12 11:02
Оценка:
V>Странно, что вы не понимаете, что ошибочно отвергнутый на самом деле обходится в сотни тысяч рублей убытка.
*недополученной прибыли
Несколько разные вещи.
Make flame.politics Great Again!
Re[3]: Тестовое задание C++ win
От: Eugeny__ Украина  
Дата: 19.01.12 13:53
Оценка:
Здравствуйте, midl, Вы писали:


M>C учетом предлагаемой зарплаты, других кандидатов вы наврятле увидите усебя на собеседовании


Хм. Как-то я пропустил, что это ДрВеб.

А вакансия забавная. Я слабо представляю, кто с указанным набором знаний пошел бы на такую зп вообще. Видимо, надеются, что кто-то пойдет работать "за громкое имя", ну так на это только студенты ведутся.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Re: Тестовое задание C++ win
От: ReFlexer  
Дата: 20.01.12 05:04
Оценка:
Бредовые тестовые вопросы составлены человеком, который не умеет собеседовать. В вопросе отсутствует какой либо смысл... что хотел узнать человек, не понятно...
Re[4]: Тестовое задание C++ win
От: sysenter  
Дата: 20.01.12 05:45
Оценка:
Здравствуйте, Кодт, Вы писали:

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


На VS throw() ни к чему не обязывает и ничего не гарантирует. Компилятор будет бросать варнинги о том, что это не реализовано, лечиться отключением через #pragma.
Re[7]: Тестовое задание C++ win
От: sysenter  
Дата: 20.01.12 05:51
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Где? В вызывающей функции он есть. Но я вообще-то не считаю, что bad_alloc надо перехватывать, за исключением редких стратегий типа — попросим 10 гиг, не получилось — тогда 5, опять не получилось, тогда 2 Кб. Как правило, программа просит столько памяти, сколько ей надо для работы


В Linux (и в винде вроде тоже) есть спекулятивное выделение памяти т.е. можно запросить и 10 гиг и получить добро от ОС, креш произойдёт потом когда приложение попробует заюзать полностью эти недоступные 10 гиг, oom killer прибъёт.
Re[4]: Тестовое задание C++ win
От: artkarma  
Дата: 20.01.12 06:01
Оценка:
E__>Здравствуйте, Eugeny__, Вы писали:

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



M>>C учетом предлагаемой зарплаты, других кандидатов вы наврятле увидите усебя на собеседовании


E__>Хм. Как-то я пропустил, что это ДрВеб.


E__>А вакансия забавная. Я слабо представляю, кто с указанным набором знаний пошел бы на такую зп вообще. Видимо, надеются, что кто-то пойдет работать "за громкое имя", ну так на это только студенты ведутся.

Ну вообще-то, да! Странная контора?? На моей памяти они уже лет 8 наверно ищут С++ программиста и регулярно несколько раз в месяц постят вакансию на разных сайтах??? Толи они ищут как ищут жену- одну и на всю жизнь, толи они набирают С++ программистов, пока не заполнят вагон, а как заполнят на этап их в Освенцим и потом берут новый вагон.
Re[5]: Тестовое задание C++ win
От: Eugeny__ Украина  
Дата: 20.01.12 11:03
Оценка:
Здравствуйте, artkarma, Вы писали:

E__>>Хм. Как-то я пропустил, что это ДрВеб.


E__>>А вакансия забавная. Я слабо представляю, кто с указанным набором знаний пошел бы на такую зп вообще. Видимо, надеются, что кто-то пойдет работать "за громкое имя", ну так на это только студенты ведутся.

A>Ну вообще-то, да! Странная контора?? На моей памяти они уже лет 8 наверно ищут С++ программиста и регулярно несколько раз в месяц постят вакансию на разных сайтах??? Толи они ищут как ищут жену- одну и на всю жизнь, толи они набирают С++ программистов, пока не заполнят вагон, а как заполнят на этап их в Освенцим и потом берут новый вагон.

Ну, с такими требованиями и зарплатой они будут искать лохов еще долго, трудно, и под смех адекватных людей.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Re[2]: Тестовое задание C++ win
От: ak_miass Россия  
Дата: 20.01.12 12:17
Оценка:
Здравствуйте, любой, Вы писали:

Л>А меня в таком коде всегда прикалывает, почему два блока нельзя за раз выделить:


Л>char *a = new char[n*2];

Л>char *b = a + n;
Л>g( a, b, n );
Л>delete [] a;

Не забывай про то, что этот код будет потом читаться\переделываться другими. Я бы "споткнулся" об это место при чтении, а читаю чужого кода я довольно много.
Re: Тестовое задание C++ win
От: Stepkh  
Дата: 01.02.12 10:19
Оценка:
Здравствуйте, amberovsky, Вы писали:

A>Здравствуйте.

A>При попытке устроится в одну фирму прислали "удалённое" тестовое задание.



Да абсолютно нормальное задание. Конечно лучше подобное давать тет-а-тет, а не удаленно. Но...

Вот есть мой тестовый кусок кода, который даю кандидатам.
С вопросом: что не нравится, какие есть проблемы и как бы вы решили:


char  * foo (char* c)
{
    char tmp [80];
    strcpy (tmp, c);
    return tmp;
}



Поверьте, из 10 кандидатов, только 2-3 человека могут указать на все проблемы.
Порядка половины может указать на одну или две.

А вот предложить решение, это уже какой-то высший пилотаж...

П.С.

И этот код я скоммуниздил из реального(!) проекта. Естественно я его причесал и выкинул ненужное, но суть та же.


П.П.С.

А вот ЧСВ у многих товарищей соискателей просто зашкаливает. Вы на улицу давно выглядывали, с людьми
общались? или только в мониторы смотрите, да в теплых помещениях сидите?
Re[2]: Тестовое задание C++ win
От: nazavrik Россия  
Дата: 01.02.12 10:58
Оценка:
Здравствуйте, Stepkh, Вы писали:

S>С вопросом: что не нравится, какие есть проблемы и как бы вы решили:



S>
S>char  * foo (char* c)
S>{
S>    char tmp [80];
S>    strcpy (tmp, c);
S>    return tmp;
S>}
S>


Интереса для.

1. Не инициализируется массив. Не критично, но не помешает.
2. Не контролируется размер передаваемых данных при копировании в массив.
3. Возвращается указатель на массив, который был создан в теле функции.

По хорошему нужно передавать в функцию два массива — источник и приемник. Проверять размерности. Использовать strncpy. м?
Re[3]: Тестовое задание C++ win
От: Abyx Россия  
Дата: 01.02.12 12:31
Оценка:
Здравствуйте, nazavrik, Вы писали:

S>>
S>>char  * foo (char* c)
S>>{
S>>    char tmp [80];
S>>    strcpy (tmp, c);
S>>    return tmp;
S>>}
S>>


N>1. Не инициализируется массив. Не критично, но не помешает.

*зачем* его инициализировать?
чтоб подавить предупреждение о неинициализированной переменной?
или чтоб в 99.9% случаев баг с отсутствием нуля на конце строки спрятать?
In Zen We Trust
Re[4]: Тестовое задание C++ win
От: Stepkh  
Дата: 01.02.12 12:35
Оценка:
Здравствуйте, Abyx, Вы писали:

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


S>>>
S>>>char  * foo (char* c)
S>>>{
S>>>    char tmp [80];
S>>>    strcpy (tmp, c);
S>>>    return tmp;
S>>>}
S>>>


N>>1. Не инициализируется массив. Не критично, но не помешает.

A>*зачем* его инициализировать?
A>чтоб подавить предупреждение о неинициализированной переменной?
A>или чтоб в 99.9% случаев баг с отсутствием нуля на конце строки спрятать?

Господа, вы льете просто бальзам на моё сердце
Re[3]: Тестовое задание C++ win
От: Stepkh  
Дата: 01.02.12 12:40
Оценка:
Здравствуйте, nazavrik, Вы писали:

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


S>>С вопросом: что не нравится, какие есть проблемы и как бы вы решили:



N>Интереса для.


N>1. Не инициализируется массив. Не критично, но не помешает.

N>2. Не контролируется размер передаваемых данных при копировании в массив.
N>3. Возвращается указатель на массив, который был создан в теле функции.

N>По хорошему нужно передавать в функцию два массива — источник и приемник. Проверять размерности. Использовать strncpy. м?


Годится
Re[2]: Тестовое задание C++ win
От: Abyx Россия  
Дата: 01.02.12 12:50
Оценка:
Здравствуйте, Stepkh, Вы писали:

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


A>>Здравствуйте.

A>>При попытке устроится в одну фирму прислали "удалённое" тестовое задание.



S>Да абсолютно нормальное задание. Конечно лучше подобное давать тет-а-тет, а не удаленно. Но...


S>Вот есть мой тестовый кусок кода, который даю кандидатам.

S>С вопросом: что не нравится, какие есть проблемы и как бы вы решили:


S>
S>char  * foo (char* c)
S>{
S>    char tmp [80];
S>    strcpy (tmp, c);
S>    return tmp;
S>}
S>



S>Поверьте, из 10 кандидатов, только 2-3 человека могут указать на все проблемы.

S>Порядка половины может указать на одну или две.

есть подозрение, что половина этих "проблем" — надуманные проблемы.

у этого кода только одна проблема — он не компилируется. (при включенных предупреждениях компилятора которые трактуются как ошибки)
при попытке ее решить возникает другая проблема — это код на Си.

дальше можно только добавить, что в моем компиляторе strcpy перегружен шаблоном функции и с размером "tmp" никакой проблемы нет, как Вы возможно считаете.
также "с" мог бы иметь тип "const char*, но это не проблема этого кода, может так было сделано специально,
а 80 такое же магическое число, как и осмысленные имена "foo" и "c"
In Zen We Trust
Re[3]: Тестовое задание C++ win
От: Stepkh  
Дата: 01.02.12 13:18
Оценка:
Здравствуйте, Abyx, Вы писали:


A>есть подозрение, что половина этих "проблем" — надуманные проблемы.


A>у этого кода только одна проблема — он не компилируется. (при включенных предупреждениях компилятора которые трактуются как ошибки)

A>при попытке ее решить возникает другая проблема — это код на Си.

A>дальше можно только добавить, что в моем компиляторе strcpy перегружен шаблоном функции и с размером "tmp" никакой проблемы нет, как Вы возможно считаете.

A>также "с" мог бы иметь тип "const char*, но это не проблема этого кода, может так было сделано специально,
A>а 80 такое же магическое число, как и осмысленные имена "foo" и "c"

Вы наверно невнимательно читали исходный пост — этот код был взят из реального(!) проекта.
И жил там полтора года, пока не пришлось брать в руки большой напильник и чинить, чинить.
По поводу не компилируется: всё зависит от вашего компилятора. Никто не помешает вам, как истинному джедаю,
отключить все предупреждения для конкретного файла. (И ведь делают так!!!) А потом приходится лезть в makefile
и материться и материться.

Вот, например, gcc 2.7 даже не муркнет на этот код. Да, древний компилятор, но.. не мы устанавливаем правила.
А вот gcc постарше кинет предупреждение:

main.cpp: In function ‘char* foo(char*)’:
main.cpp:6:9: warning: address of local variable ‘tmp’ returned [enabled by default]

И что? да ничего — соберется все за милую душу.

А что будет мешать нам собираться — то удалим (-Werror нам мешает)

Тут уже больше относится к дисциплине, но, ведь человек должен понимать что он делает?

Или был такой реальный кусок кода:



 char* foo (...)
 {
      static char* tmp;
      tmp = malloc(...)
      return tmp;
 }

 void big_fun ()
 {
      for (i =0; i < size; i++)
      {
          char* ptr = foo (...)    
      }

 }


и без единого free()...


А почему там static появился? ААА... вот именно потому чтобы обойти сей варнинг от компилятора.
(Это добавило мне пару седых волос)

Так что это не надуманные проблемы — это суровый быт.

Увы.
Re[2]: Тестовое задание C++ win
От: minorlogic Украина  
Дата: 01.02.12 13:59
Оценка:
я бы сказал что задание более бредовое чем в изначальном посте.
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re: Тестовое задание C++ win
От: minorlogic Украина  
Дата: 01.02.12 14:06
Оценка:
я пару раз давал такое задание , и встречал полное непонимание.

-----
" Програмисту дали задание реализовать функцию которая возвращает текущее время с точностью до секунды. В результате он показал заголовочный файл с таким объявлением

currentTime.h

int getCurrentTime();


Вопрос , какие вы видите проблемы и как бы вы смогли улучшить этот код?
"
-----

Интересно что скажет уважаемый All на это задание ?
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[3]: Тестовое задание C++ win
От: Stepkh  
Дата: 01.02.12 14:20
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>я бы сказал что задание более бредовое чем в изначальном посте.


Да ну?

inet_ntoa() ничего не говорит? вернее её специфические особенности?

А ведь она практически полная копия вышеупомянутого задания... Ну за исключением входного параметра

И я прошу , данные задания не направлены на то чтобы "зачморить" соискателя или показать "крутость" собеседующего.

Можно сделать такое тестовое задание, что без знания линейной алгербы и не решить.

Это задание по сути выявляет базовые знания от которых можно отталкиваться и обучать уже предметной области.

А заодно и посмотреть как человек реагирует на подобные ляпы и казусы.
Re[4]: Тестовое задание C++ win
От: nazavrik Россия  
Дата: 01.02.12 14:36
Оценка:
Здравствуйте, Abyx, Вы писали:

A>*зачем* его инициализировать?

A>чтоб подавить предупреждение о неинициализированной переменной?
A>или чтоб в 99.9% случаев баг с отсутствием нуля на конце строки спрятать?

Ну это как в анекдоте. У Маши было 8 яблок. 2 яблока она отдала Пете. Вопрос: сколько яблок у Пети?
Re[2]: Тестовое задание C++ win
От: landerhigh Пират  
Дата: 02.02.12 00:28
Оценка:
Здравствуйте, Stepkh, Вы писали:

S>С вопросом: что не нравится, какие есть проблемы и как бы вы решили:



S>
S>char  * foo (char* c)
S>{
S>    char tmp [80];
S>    strcpy (tmp, c);
S>    return tmp;
S>}
S>



S>Поверьте, из 10 кандидатов, только 2-3 человека могут указать на все проблемы.

S>Порядка половины может указать на одну или две.

Проблем в этом коде всего две.
1. Это не C++
2. Смысла в этом коде нет.

Ввиду пунка 2 искать дальнейшие проблемы и спорить до усера о необходимости инициализации tmp и допустимости возврата указателя на локальную переменную совершенно бессмысленно, этот код подлежит отправке "на помоечку".
www.blinnov.com
Re[4]: Тестовое задание C++ win
От: qqqqq  
Дата: 02.02.12 01:57
Оценка:
Tы знаешь, твои задачки трудны не тем, что они какие-то шибко закавыристые, а тем, что непонятно зачем вообше все это надо. Все таки должна быть хоть какая то логика пусть даже и в тестовых задачах. Подозреваю, что многие из опрошенных были в ступоре от функции, которая возвращает ту же самую информацию, что была в нее подана как аргумент, да еще предварительно покопировав ее в локальную строку. Собеседование — это тот еще стресс. Ты бы хотя бы функции и пременные назвал так, чтобы человек с без телепатических способностей мог догадаться, что твоя функция фууу должна была делать. Короче, правильный ответ на вопрос что не нравится — "Да, все", а как исправить — "А что надо-то?".
По поводу этой фуу с маллоком, тоже неясно, зачем она вообще и как ты хочешь ее улучшить. Что в ней плохого? То, что она без единого free? Так может она и есть аллокатор, и удалять не ее забота. Или ты намекаешь что функция большое_веселье должна была удалять, так опять не понятно зачем ей столько буферов в цикле если можно было бы одним обойтись, причем не обязательно динамическим. Да и статик/нестатик — как это влияет: разве функция не возвращает адрес из маллока? Ты что убрал статик — и сразу все починилось?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.