Задача для непрограммистов

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Парни, я тут пишу давно обещанный этюд по работе с динамической памятью. Нужна Ваша помощь. Очень хочется посмотреть ваши соображения по поводу одного кода. Вопрос простой:

почему он печатает именно это?

Очень прошу профессионалов не подсказывать. Для написания материала мне очень важно почитаь мнения новичков и непрограммистов.

Вот собственно код:

void awfulShitCode(const char * s)  {
	*((long*)s+1)=1702125896l;
}

void setup(void) {
	Serial.begin(115200);
	awfulShitCode("Oh!");
	Serial.println("Love you!");
}

void loop(void) {}

 

Joiner
Offline
Зарегистрирован: 04.09.2014

Ни че не понимаю в этом скетче...но если букву "l" убрать из длинного числа в строке 2, и вместо нее поставить 1, то пишет уже немного другое (СМ<ц you !).

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Шайтан!

 

ptr
Offline
Зарегистрирован: 28.05.2016

.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

помня о почтенном цинизме автора я даже не стал таблицу ASCII кодов проверять, там ведь  Hate получится? Так? ;) ;) ;)

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

wdrakula пишет:

помня о почтенном цинизме автора я даже не стал таблицу ASCII кодов проверять, там ведь  Hate получится? Так? ;) ;) ;)

я, к своему стыду, на f..k подумал

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Блин, все "новички" собрались. Ну, я же просил, мужики :)))

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

ЕвгенийП пишет:

Блин, все "новички" собрались. Ну, я же просил, мужики :)))

а сакральное никто не выдавал...

ptr
Offline
Зарегистрирован: 28.05.2016

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

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

ptr пишет:

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

вы не правы

ptr
Offline
Зарегистрирован: 28.05.2016

Gippopotam пишет:

вы не правы

Тогда где бага?

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

ptr пишет:

Gippopotam пишет:

вы не правы

Тогда где бага?

при чем тут?

просили-же суть не выдавать...

ptr
Offline
Зарегистрирован: 28.05.2016

Gippopotam пишет:

просили-же суть не выдавать...

Значит Вы не новичок, а говорите за них )

Joiner
Offline
Зарегистрирован: 04.09.2014

От имени новичков говорю: "Сдаемся."   Я вообще не понимаю как работает функция, обозначенная в строке 1. Что там за звездочки, и вообще что там за фигня, похожая на длинное число...Если букву "l" поменять на другую, то компилятор выдает всякие непонятные сообщения, типа "инвалид суффикс", или "тип с фиксированной точкой не поддерживается в С".

Гуглением нашел, что это что-то, связанное с адресами, что память там "read only", но разные компиляторы ведут себя по-разному......короче, темный лес для новичка.

Нам что-то бы попроще:)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Joiner пишет:

функция, обозначенная в строке 1. 

Ну, с ангийским-то нормально? На всякий случай - эта функция назывывается "ужасный говнокод" - так вот, он и есть!

Joiner пишет:

Если букву "l" поменять на другую, 

Ну, поменяйте на "L" - тоже нормально сработает. Можно даже на "UL".

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

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

Хотя, да .. вывод изменится. Блин .. проверять надо. Если PROGMEM то нет, ничего не произойдет .. или он во флеш "перепишет" или скопипастит в SRAM и там "нагадит"? .. забыл ужо.

ptr
Offline
Зарегистрирован: 28.05.2016

Arhat109-2 пишет:

но на конкретно этом выводе это отразиться вроде как не должно. Доберусь домой - проверю, уже интересно.

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

 

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

Ответ новичка: У мну сейчас ардуино нет, но онлайн эмулятор почему то выдал значек ø.что явно не соответствует тому чего мы просили сделать. А в говновойде мы берем чар переменную с какими то звездочками и пытаемся сделать ее лонгом, причем тоже с какими то звездочками, при этом добавляем 1 и приравниваем к какому то большому числу. как это повлияло на нашу прозьбу написать в сириал о любви не понятно...

п.с. ардуино сказало что ненавидит меня, я ей 22О на вход подал, она пшикнула и вышел синий дым...
Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Гы .. как раз интересно проверить он во флеш изменит константу через lpm или таки нагадит в SRAM? :)

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Так и хочется воскликнуть рекламным слоганом: "говнее кода не видал!" ;) Шутка, это далеко не самый страшный говнокод.

MSVS2013 свалился в exception.

Ассемблерный листинг после ардуины - голову сломаешь :)

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Arhat109-2 пишет:

Гы .. как раз интересно проверить он во флеш изменит константу через lpm или таки нагадит в SRAM? :)

Архат! Вы меня пугаете! Это не прогмем константа, какой, в жоппу, флеш?????????

Это просто литерал в памяти. Они, млеать, лежат последовательно, по порядку объявления в программе.

Добавьте в луп еще один прит ТАКОЙ ЖЕ "лав ю", и не будет "хейт ю" первым, а добавите в луп принт ЛЮБОЙ ДРУГОЙ строки, будет первым "хейт", а потом то, что в лупе.

Кстати, Евгений, это хороший вопрос новичкам: А почему эфект пропадет, если такой же литерал использовать в лупе? Это как раз особенность ИДЕ, который проделывает нечто ДО запуска компилятора.

-------------------------

Архат! Смотришь на Ваш код - вроде хороший програмист, читаешь то, что Вы пишите - жуть с кошмариками! Как это в одном человеке помещается?

ptr
Offline
Зарегистрирован: 28.05.2016

Arhat109-2 пишет:

Гы .. как раз интересно проверить он во флеш изменит константу через lpm или таки нагадит в SRAM? :)

А Вы в курсе, чем различается запись:

const PROGMEM char love[] = "Love you!";

и

const char love[] = "Love you!";

?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

да, кстати и китайская нанка и амперковская леонардо - ОК.

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

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Кстати, еще про платы: китайская нанка немного быстрее. У меня есть тест с синусами степенями и прочей мутью, причем специально так сделанный, чтобы шибко умный компилятор не оптимизировал, что не надо. Так вот на Амперковской леонарде и на нанке - разные средние времена и нанка быстрее процентов на 10, если я правильно помню результаты. Хотя вычислительное ядро вроде одинаковое.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Да забыл ужо что он const во флеш сам не преобразует .. конечно всё будет изгажено в SRAM ..

P.S. могу и не писать .. говнокодьте себе на здоровье .. может как раз "код вроде хороший" (спасибо конечно, никогда вот сам не уверен что он действительно хорош), потому что пишу так, как считаю верным не взирая на "догмы"? Об чем и Вам донести пытаюсь .. может стоит вчитаться раньше чем оголтело возражать, не? :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

wdrakula пишет:

Кстати, Евгений, это хороший вопрос новичкам: А почему эфект пропадет, если такой же литерал использовать в лупе? Это как раз особенность ИДЕ, который проделывает нечто ДО запуска компилятора.

Да, нет, должно быть всё нормально. наверное, там у Вас ещё какая константа затесалась.

Константы располагаются в памяти подряд. В данном случае первой идёт 4-байтовая "Оh!", а за ней "Love you". Поэтому, когда я к адресу "Оh!" прибавляю 4 (прибаляю 1, но указатель уже преобразван к long *), то как раз попадаю на начало строки "Love you". Если между ними затешется ещё одна константа - то адреса сместятся.

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

ЕвгенийП пишет:

wdrakula пишет:

Кстати, Евгений, это хороший вопрос новичкам: А почему эфект пропадет, если такой же литерал использовать в лупе? Это как раз особенность ИДЕ, который проделывает нечто ДО запуска компилятора.

Да, нет, должно быть всё нормально. наверное, там у Вас ещё какая константа затесалась.

Константы располагаются в памяти подряд. В данном случае первой идёт 4-байтовая "Оh!", а за ней "Love you". Поэтому, когда я к адресу "Оh!" прибавляю 4 (прибаляю 1, но указатель уже преобразван к long *), то как раз попадаю на начало строки "Love you". Если между ними затешется ещё одна константа - то адреса сместятся.

все, интриги больше не будет?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

порядок меняется, после обработки ИДЕ loop компилируется раньше, чем setup. и "Oh!\" + 4 не попадает на "Lov..."/

Вот снимки экрана:

 

 

==================================

Я же много раз писал, что спорить со мной не только неприятно, но и бесполезно, уж простите.

====================

ЗЫ: Это китайская нанка на 328

Joiner
Offline
Зарегистрирован: 04.09.2014

Пез...дец! Новички тренируются! Нахрена новичков было звать? Туман полнейший!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Joiner пишет:

Нахрена новичков было звать? 

Я же говорю, чтобы лучше написать этюд. Хотел послушать, что скажут люди, какие идеи выдвинут.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Joiner пишет:

Пез...дец! Новички тренируются! Нахрена новичков было звать? Туман полнейший!

А что именно Вам непонятно?

Тема посвящена тому, что неаккуратным обращением с памятью можно так загадить свою программу, что, вместо "Лав", "Хейт" получится. На эту тему Евгений будет писать новый, полезный начинаюшим, этюд.

Если непонятно - то очень советую разобраться в этом примере. Это спасет от разной херни в будущем.

==============================================================

Пример про память из моей жизни, если интересно:

Пишу кусок сетевого кода на АРМ процессоре под линухом. Давно. TCP - вариант работает на ура, UDP - вообще не работает. На третий день начинаю сходить с ума! Вставляю отладочные принты по очереди прямо в ядро. Дохожу ДО САМОГО НИЗА. До драйвера сетевой карты на борту платы.

Там kalloc -ом выделается память для  приема пакета. БЕЗ ВЫРАВНИВАНИЯ НА 4 байта!!!!!!!!!!!!!

А в АРМ, не знаю как в современных, а тогда было так, что если читать 32-битное слово с адресе НЕ ДЕЛЯЩЕГОСЯ на 4, то первое и второе полусова меняются местами. Вот так вот, это даже не документировано, потому, что ТАК НЕ ПРОГРАМИРУЮТ, разработчик чипа не думал о ебанутых индусах.

А правка последствий этой дряни была в коде даже не IP, а UDP_recv. Там два индуса слова просто переставили, с коментарием, типа того, что неведомая херня, но так работает. ;) ;) %). Вот Вам и память.

ssss
Offline
Зарегистрирован: 01.07.2016

wdrakula пишет:

А в АРМ, не знаю как в современных, а тогда было так, что если читать 32-битное слово с адресе НЕ ДЕЛЯЩЕГОСЯ на 4, то первое и второе полусова меняются местами. Вот так вот, это даже не документировано, потому, что ТАК НЕ ПРОГРАМИРУЮТ, разработчик чипа не думал о ебанутых индусах.

Один и тот же код может в М3 работать, а в М0 - нет, выскакивает в исключение. Так что, в новых получше, но бдительность один фиг нужна.

toc
Offline
Зарегистрирован: 09.02.2013

Joiner пишет:

Пез...дец! Новички тренируются! Нахрена новичков было звать? Туман полнейший!

вторая буква "и"

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

toc пишет:
Joiner пишет:

Пез...дец! Новички тренируются! Нахрена новичков было звать? Туман полнейший!

вторая буква "и"

При условии, что ни одна зараза в памяти по указателям не порылась :)