Что тут неправильного?

Все, что вы хотели знать о программизме, но боялись спросить.
Ответить
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

Сообщение aissp »

я не совсем понимаю зачем спрашивать если не читать ответы?

S( int k = 0 )
{
if( k ) p = new char[k];
else p = NULL;
}
~S() { delete[] p; }
}
Ето твой код? Тобой написанный?

По русски если буква к равна нулю то буква р в твоем коде получает значение нуль (в твоем коде)

Далее при отрабки деструктора вызовется


delete[] NULL согласно написанном тобой коду. Ето часо плохо.
При таком конструкторе как ты написал надо писать
if(p) delete[] p; Но и ето не очень правильно лучше заранее проинициализировать указатель нулем без всяких елзе.
tiasur
Маньяк
Сообщения: 1510
Зарегистрирован: 26 фев 2006, 10:00
Откуда: offline

Сообщение tiasur »

Ето твой код? Тобой написанный?
Извини, я думал ты об оригинале.
delete[] NULL согласно написанном тобой коду. Ето часо плохо.
Чем? Серьезно незнаю.
Но и ето не очень правильно лучше заранее проинициализировать указатель нулем без всяких елзе.
Пробовал не дает, возникает ошибка компиляции:
pure specifier can only be specified for functions
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

Сообщение aissp »

Гуд давай степ бай степ.

первоначальный код задачи:

class S
{
char *p;
int n;
public:
S( int k = 0 )
{
n = k;
if( n ) p = new char[n];
}
~S() { delete[] p; }
};

int main()
{
S s;
return 0;
}

Вопрос для чего задана ета задача?
Ответ - проверит правильно ли кагдидат обслуживает освобожднеие памяти. Замтит ли кандидат что если n = 0 то память не выделяется и освобождаться соотв не должна.

Правильный ответ следующий - p=0.... в конструкторе
ипроверка на нуль в дуструкторе. Есть соотвествющие гарантии что если память была выдлена то указатель не нуль и соотв надо ее убивать. Больше от кандидата ничего не требуется и код менять впрочем тоже. Дальше мелочи

что есть опеределение

class myClass {
obj qq;
...

myClass() {qq = ...;}
}

Данный код означает что для обхекта куку сначала вызывается конструктор по умолчанию а затем конструктор копии. Чтобы етого избежать qq необходимо инициализировать писком до фигурных скобок конструктора.


ОК теперь твой код. Ты взял и вукинул n вопрос зачем? Чему он мешал, к сути задачи он не относится, какой вывод? Кандидат не совсем понял о чем его спрашивают. Дальше ок ты приравнял указатель нулю но в условном операторе. Я готов согласиться что кандилат знает что произойдет если исключение возникнет в первой ветке ифа. Я даже готов поверить что кандидат в курсе как компилятор изменит данный иф, но канонически правильно писать
n(k) {
p = 0;
if (n) p = new char[n];
}
и в деструкторе опять проверка на нуль
if(p) delete[] p;

Иначе кандидат бы сильно развил свой ответ разными заморочками.

это все что ожидается в ответе на ету задачу, остальное сильное насасыванеи мизеров.
tiasur
Маньяк
Сообщения: 1510
Зарегистрирован: 26 фев 2006, 10:00
Откуда: offline

Сообщение tiasur »

aissp, спасибо!
Главное тут это было инициализировать указатель в конструкторе. Я это пропустил.
А какие проблемы с delete[] NULL?
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

Сообщение aissp »

Ето странно что у тебя ето не выбросило корку. Обязано выбрасывать. Стандарт не гарантирует корректного поведения компилятора в таких случаях (gcc например тут же бросает корку)
tiasur
Маньяк
Сообщения: 1510
Зарегистрирован: 26 фев 2006, 10:00
Откуда: offline

Сообщение tiasur »

Извини, не знаю, что ты подразумеваешь под коркой. Однако выдает ошибку код:

Код: Выделить всё

delete[] NULL;
а этот нет:

Код: Выделить всё

		int *p = NULL;
		delete[] p;
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

Сообщение aissp »

ой сорри, жаргон. Под коркой я подразумеваю ошибку времени выполнения или другими словами крах программы. Существуют способы при крахе программы распечатывать содержимое стека или в просторечии корку
tiasur
Маньяк
Сообщения: 1510
Зарегистрирован: 26 фев 2006, 10:00
Откуда: offline

Сообщение tiasur »

Понял. Спасибо.
Однако, возвращаясь к предыдущему сообшению получается, что первый код не равен второму.
int *p = NULL;
delete[] p;

Код: Выделить всё

delete[] NULL;
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

Сообщение aissp »

ага ето высказывание прально, и должно вызывать ощибку времени исполнения. За котой куей (не китайский) тут же бежит за пивом, коллеги показыва.т пальцами, кастомер издеваецца над начальство и начальство в полный рост ставит девелопера в позу. А девелопер? А что ему остается - он расслабляется и пытается получить удовольствие ххоть таким путем.
tiasur
Маньяк
Сообщения: 1510
Зарегистрирован: 26 фев 2006, 10:00
Откуда: offline

Сообщение tiasur »

Все равно не пойму зачем делать проверку:

Код: Выделить всё

if (p) delete[] p;
Аватара пользователя
aissp
Маньяк
Сообщения: 2710
Зарегистрирован: 07 ноя 2005, 09:51

Сообщение aissp »

ето довольно просто

1. рассмотрим объявление
blabla* p;

каким значением инициализирует компилятор указатель? Ответ каким то мусором. при попытке изничтожить данный муор например способом
delete p; что будет делать компилятор? Они обратиться к енджеру хипа с просьбой считать блок памяти на который указывает указатель p отныне свободным. Что произойдет если менждер кучи не найдет такого указателя? При условии что память выделяется часто и соответсвенно ето операция оптимизирована? Мне кажется программа рухнет. То же самое и с нулем? Что происходит в потрахах компутера када ты пытаешься удалить нуль? Заметь соотвествуюший аллокатор он оптимизирован он не делает проверок потому как ето время - он просто заноит ето блк готов для дальгейщего распределенения. В большинстве слычаев ето вызвает крах программы. Итак,
1. нам надо убедиться что указатель инициализирован значение которое мы знаем и по которому мы можем судить была ли выделена память или нет. Единственное значение такого рода ето нуль. Если память на указатель была выдлена - он не нуль. Соотвественно мы можем принять рещение, возвращать память менеджеру свободной памяти или не возвращать (еще раз подчеркну мы н в курсе что там делает етот манагер) по значению указателя. Если он нуль - память не выделялась (манагером) и нам нет смысла ее очищать (возвращать манагеру для дальнейшего рапределения) не нуль - память была выделена - надо ее вернуть.


Да и лирическое отступление - мое сугубое мнение если ваша позиция больше чем жуниур и вам задают такие задачи, то надо серьезно задуматься о том надо ли вам туда итить. Потому как либо от вас требуют знать как устроен менеджер хипа конкретного компилятора, че отличаются разные типы оптимизации для данного компилятора, а также ньюансы стандарта плюсов, что с моей точки зрения стоит в районе стошки в целом, либо над вами просто издеваются...

Да для справки у нас phd в области ай ти не смог рещить задачу как написать функцию которая позвращает указатель на самою себя... Ето говорит о том что рещать такие задачи в жизни не смое главное:) \


Все за сим поехал за очередным пузыриком
tiasur
Маньяк
Сообщения: 1510
Зарегистрирован: 26 фев 2006, 10:00
Откуда: offline

Сообщение tiasur »

Нашел в старой книжке Borland, где Kent Reisdorph пишет:
Second, it is okay to delete a pointer that has been set to 0.

И ниже немнго:
In this case you don't really care whether memory for the object was ever allocated because the call to delete is safe whether the pointer points to an bject or is NULL.

По лирике. Я не претендую на джуниорскую позицию и даже на позицию программиста.
Просто одна работа закончилась, а вторая ещё не началась. Повесил резюме на Монстер и, видимо, по случайности или недоразумению стал звонить Майкрософт. Уже было два телефонных интервью и хотели устроить ещё два в понедельник. Ну а перед тем как... шлют задачки, которые интересно решать.
tiasur
Маньяк
Сообщения: 1510
Зарегистрирован: 26 фев 2006, 10:00
Откуда: offline

Сообщение tiasur »

Вот кстати ещё одна задачка. Мне удалось её быстро решить и может быть поэтому она мне понравилась :)
#include <stdio.h>

#define LEAST(x,y) ((x) < (y) ? (x) : (y))

char *puzzle = "A real puzzle";
int main()
{
int least=10000;
char *p = puzzle;

while( *p )
{
least = LEAST( least, *p++ );
}
printf( "The least char is '%c'\n", least );
return 0;
Аватара пользователя
ajkj3em
Маньяк
Сообщения: 2063
Зарегистрирован: 12 ноя 2006, 06:53

Сообщение ajkj3em »

aissp писал(а):Ето странно что у тебя ето не выбросило корку. Обязано выбрасывать. Стандарт не гарантирует корректного поведения компилятора в таких случаях (gcc например тут же бросает корку)
алЕксий, что вы там курите, голубчик ? я аж новый аккаунт не поленился зарегистрировать ..

(kstati, administratzija, kakogo, sprashivaetsja, hrena nel'zja ispol'zovat' moj ljubimyj mailinator.com, no pri wtom vse ostal'nye free email hostings - mozhno ? i kak mne otvechat' na proverochnyj vopros pro stolitzu kanady, esli u menja ne stoit russkoj raskladki ?)

поведение что free, что delete c нулевым аргументом конечно же определено стандартами. секция 3.7.3.2 в с++ в частности
Аватара пользователя
ajkj3em
Маньяк
Сообщения: 2063
Зарегистрирован: 12 ноя 2006, 06:53

Сообщение ajkj3em »

tiasur писал(а):Вот кстати ещё одна задачка. Мне удалось её быстро решить и может быть поэтому она мне понравилась :)
no offense - но это детский сад, хотя в принципе грабли популярные..
Ответить