Re[2]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 14:48
Оценка: -3 :))) :)))
R>Если вылетит исключение при выделении памяти под b, то память для a не будет освобождена -> утечка память.
Ну какая утечка? Если вылетит исключение в приведенном фрагменте, программа просто завершится и всю память почистит ОС.
Да здравствует мыло душистое и веревка пушистая.
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[5]: Тестовое задание C++ win
От: amberovsky  
Дата: 30.11.09 14:54
Оценка:
Здравствуйте, SaZ, Вы писали:

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


Вы считаете ошибку со слешем причиной отказать?
Re[2]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 15:42
Оценка: -2
К>А вот метнуть исключение функция g() может запросто.
А вот это маловероятно. Сигнатура функции предполагает, что она написана не на С++, а на С. А значит, скорее всего, никаких исключений она бросить не может.
И по большому счету, я вижу реальную проблему только в printf.
Да здравствует мыло душистое и веревка пушистая.
Re[3]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 15:45
Оценка: 1 (1) +2
_>чтобы испортить указатели ф-я не должна стрелять в стек, она должна всего лишь вызвать для них delete и лечится это передачей константных указателей
Вообще-то, никто не мешает вызвать delete для константных указателей.
Да здравствует мыло душистое и веревка пушистая.
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[4]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 15:57
Оценка: -3
SC>Каким образом она это указывает?
Способом передачи параметров. Если бы она была написана на С++, она бы принимала два вектора.
Да здравствует мыло душистое и веревка пушистая.
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: Тестовое задание 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[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[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[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
От: alexander_st Россия  
Дата: 30.11.09 18:38
Оценка: -4 :)
Здравствуйте, Vamp, Вы писали:

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

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

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

V>Способом передачи параметров. Если бы она была написана на С++, она бы принимала два вектора.
а если эта ф-я экспортируется из dll она бы тоже принимала 2 вектора?
а исключение по выделению памяти или по какому нить доступу по кривому указателю она тоже не может кинуть?
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[6]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 19:01
Оценка: -1
_>а если эта ф-я экспортируется из dll она бы тоже принимала 2 вектора?
Дело не в экспорте, а в языке. Зачем С++ функции принимать указатели, если можно векторы?

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

С++ исключение, если она написана на С — не может.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: Тестовое задание C++ win
От: Vamp Россия  
Дата: 30.11.09 19:12
Оценка: +2 :)
K>какие авто_птр?? какой буст??? Зачем усложнять жизнь в тривиальном куске кода? KISS!
А ведь ты не понял принцип КИСС.
Да здравствует мыло душистое и веревка пушистая.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.