тут при чтении книжки наткнулся на странный код...
помедетитировал под отладчиком над ним первый цикл изменяет '\0' в конце строки на 1
и выходит а второй предположительно может шагать по оперативной памяти
очень долго за пределами строки пока не встретит терминатора случайно оказавшегося
где то в оперативной памяти и декрементировав его остановиться
это ошибка автора книги да ?
String^ str = "Nish wrote this book for Manning Publishing";
interior_ptr<Char> ptxt = const_cast< interior_ptr<Char> >(
PtrToStringChars(str));
interior_ptr<Char> ptxtorig = ptxt;
while((*ptxt++)++);
Console::WriteLine(str);
while((*ptxtorig++)--);
Console::WriteLine(str);
You go through the string using a while-loop that increments the pointer as well as
each character until a nullptr is encountered, because the underlying buffer of a
String object is always nullptr-terminated. Next, when you use Console::Write-
Line on the String object, you can see that the string has changed to
Ojti!xspuf!uijt!cppl!gps!Nboojoh!Qvcmjtijoh
You’ve achieved encryption! (Just kidding.) Because you saved the original pointer
in ptxtorig, you can use it to convert the string back to its original form using
another while loop. The second while loop increments the pointer but decrements
each character until it reaches the end of the string (determined by the
nullptr). Now, when you do a Console::WriteLine, you get the original string:
Nish wrote this book for Manning Publishing
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>это ошибка автора книги да ?
Конечно, да. Ты посмотри внимательно, что он пишет:
You go through the string using a while-loop that increments the pointer as well as each character until a nullptr is encountered, because the underlying buffer of a String object is always nullptr-terminated.
Если Сивакумар путает nullptr и '\0' (он же ASCII-код NUL), то что уж тут говорить.
Причём я догадываюсь, как именно он спутал. В эпоху до С++11 нуль-указатель был NULL, и много кто смешивали в литературе NULL и NUL; тем более, что компилятор прощал ошибку вида
char c;
... if(c == NULL) ...
Но вот захотелось товарищу Сивакумару привести всё к современному виду, а получился энциклонг.
у меня еще закрались сомнения так как автор пишет про .NET String^ то может и правда их внутренний буфер заканчивается не двумя байтами которые представляют в юникод строках '\0' а 4 или 8 в зависимости от платформы так как он упомянул nullptr
но во первых даже если это и так то после работы второго цикла на x86 машине в памяти вместо \x00\x00\x00\x00 будет уже \x00\x00\xFF\xFF тоесть в любом случае остается "побочный эффект" от этих циклов даже если предположить что писал он это исходя из того что зарубился что в конце строки всегда кусок памяти размером с указатель на этой платформе
а во вторых такой код повредит память в "обычном" C++ так как во втором цикле пока ищет '\0' где то в оперативной памяти (так как свой превратил в FF в певом цикле) попутно будет декрементировать каждый байт уже чужой памяти
Здравствуйте, Figaro, Вы писали:
F>Спасибо за интимные подробности... Следующий раз напишите статью на РСДН — сразу как кончите
Статью о том, почему не надо в одном выражении использовать 100500 экскрементов? Так уже сто раз всё написано везде. Но придуркам, желающим показать свою кулхацкерность, эти статьи не указ.
Этот же кусок можно переписать так:
for (;;)
{
if (!(*ptxt)) break;
++(*ptxt);
++ptxt;
}
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>Всем привет
J>тут при чтении книжки наткнулся на странный код... J>помедетитировал под отладчиком над ним первый цикл изменяет '\0' в конце строки на 1 J>и выходит а второй предположительно может шагать по оперативной памяти J>очень долго за пределами строки пока не встретит терминатора случайно оказавшегося J>где то в оперативной памяти и декрементировав его остановиться
J>это ошибка автора книги да ?
Это всё от нетерпимости по национальному признаку!
Надо написать гневное письмо в комитет об ущемлении прав индусов — пусть внесут в стандарт требование двойного нуля в конце однобайтных строк — тогда несомненно гениальная программа сразу станет работать корректно!
Здравствуйте, CEMb, Вы писали:
CEM>Это всё от нетерпимости по национальному признаку! CEM>Надо написать гневное письмо в комитет об ущемлении прав индусов
Не написать, а надиктовать аудиозапись на ингрише.
Хотя, написать им на руинглише тоже непогано будет.
CEM>пусть внесут в стандарт требование двойного нуля в конце однобайтных строк — тогда несомненно гениальная программа сразу станет работать корректно!
Терминатором должен быть \0\0\1\1\377\377 — тогда гораздо больше гениальных программ смогут работать корректно.
Здравствуйте, TarasB, Вы писали:
К>>Терминатором должен быть \0\0\1\1\377\377 — тогда гораздо больше гениальных программ смогут работать корректно.
TB>377?
Здравствуйте, Кодт, Вы писали:
К>>>Терминатором должен быть \0\0\1\1\377\377 — тогда гораздо больше гениальных программ смогут работать корректно.
тогда уж надо в стандарте разрешить всем использовать свои стандарты
TB>>377?
К>
while(++*str++);
Это конструкция упаковывает 377 в байт, дааа боюсь, коллега, мы можем так уйти за радиус Шварцшильда в байте и свернём в бит всю информационную вселенную!
Здравствуйте, CEMb, Вы писали:
CEM>Это конструкция упаковывает 377 в байт, дааа боюсь, коллега, мы можем так уйти за радиус Шварцшильда в байте и свернём в бит всю информационную вселенную!
1) Не позорься
2) Проверься на баги в своих программах
Потому что грабельки-то детские. Но ударить могут больно.
Хотя конечно, char у нас знаковый, а отрицательные коды в строках сделать нельзя, поэтому неизбежно устраиваем целочисленное переполнение через верхнюю границу ASCII \177.
Но это должно быть законно. (лень лезть в стандарт за номерами параграфов).
Здравствуйте, Кодт, Вы писали:
CEM>>Это конструкция упаковывает 377 в байт, дааа боюсь, коллега, мы можем так уйти за радиус Шварцшильда в байте и свернём в бит всю информационную вселенную!
К>1) Не позорься К>2) Проверься на баги в своих программах К>Потому что грабельки-то детские. Но ударить могут больно.
К>Хотя конечно, char у нас знаковый, а отрицательные коды в строках сделать нельзя, поэтому неизбежно устраиваем целочисленное переполнение через верхнюю границу ASCII \177. К>Но это должно быть законно. (лень лезть в стандарт за номерами параграфов).
А, понял, в чём дело... я не пользуюсь восьмеричным форматом, я всё в хексе пишу. И таких граблей у меня нету. А возможностями переполнения сам пользуюсь.
А про радиус Шварцшильдта для байта была прикольная шутка "Как сделать dev/nul? Берём любой байт..."