|
IAR 4.41A & C++ |
|
|
|
Sep 21 2007, 08:13
|
Участник

Группа: Участник
Сообщений: 63
Регистрация: 21-09-07
Из: СССР
Пользователь №: 30 719

|
Имеем простой классический код: Код class TMenu { public: TMenu(); ~TMenu(); int Show(int); private: char menu[7][17]; int x,width,len,ptr; };
TMenu *m=new TMenu(); m->Show(1); delete m; Компилируется отлично, без ошибок. Пишем в камень (AT91SAM7XC256), радуемся красивому зависанию. До оператора new все работает, затем просто виснет проц. Объявление в статике все решает, но держать в памяти много объектов не очень здорово. Писать для каждого нового меню отдельную процедуру, чтобы держать все в стеке тоже не очень - тогда с классами нет необходимости возиться. Думал, что там с heap проблема - никаких. malloc() работает.
--------------------
Сомневаюсь, и вам советую!
|
|
|
|
|
Sep 21 2007, 09:28
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(mungo @ Sep 21 2007, 12:13)  TMenu *m=new TMenu(); М.б. TMenu *m=new Menu(); или TMenu *m=new Menu; или м.б. TMenu Menu; TMenu *m=&Menu; PS. Интересно, что Вы делаете наладонник ?
Сообщение отредактировал alexander55 - Sep 21 2007, 09:36
|
|
|
|
|
Sep 21 2007, 09:52
|
Участник

Группа: Участник
Сообщений: 63
Регистрация: 21-09-07
Из: СССР
Пользователь №: 30 719

|
Цитата(alexander55 @ Sep 21 2007, 12:28)  М.б. TMenu *m=new Menu(); или TMenu *m=new Menu;
или м.б. TMenu Menu; TMenu *m=&Menu;
PS. Интересно, что Вы делаете наладонник ? Нет, всего лишь кассовик...
--------------------
Сомневаюсь, и вам советую!
|
|
|
|
|
Sep 21 2007, 10:12
|
Участник

Группа: Участник
Сообщений: 63
Регистрация: 21-09-07
Из: СССР
Пользователь №: 30 719

|
Цитата(jorikdima @ Sep 21 2007, 13:03)  Крутые советы mungo Сделайте пошагам. Код вроде нормальный. А просто динамически какой нибудь массив int[] выделить удается? Да, проверил, и точно - при любых раскладах не работает new. Код char *s; s=new char[10]; delete [] s; Ситуация та же. Доходит до new и тут же умирает.
--------------------
Сомневаюсь, и вам советую!
|
|
|
|
|
Sep 21 2007, 10:37
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(mungo @ Sep 21 2007, 16:12)  Да, проверил, и точно - при любых раскладах не работает new. Код char *s; s=new char[10]; delete [] s; Ситуация та же. Доходит до new и тут же умирает. У меня тоже нет готового ответа, но... как вариант: new -- ведь оператор. А что если его преопределить, т.е. написать реализацияю своего через sizeof и malloc. Отпишите здесь обязательно, как удалось побороть/не побороть проблемку.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Sep 21 2007, 10:41
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(mungo @ Sep 21 2007, 14:12)  Да, проверил, и точно - при любых раскладах не работает new. Код char *s; s=new char[10]; delete [] s; Ситуация та же. Доходит до new и тут же умирает. Может Heap как-то не так настроен. И все-таки не пойму, зачем в кассовом аппарате завязываться с динамической памятью (просветите, серьезно, очень интересно).
|
|
|
|
|
Sep 21 2007, 10:58
|
Участник

Группа: Участник
Сообщений: 63
Регистрация: 21-09-07
Из: СССР
Пользователь №: 30 719

|
Код 693 void xxx() 694 { \ ??xxx: \ 00000000 10B5 PUSH {R4,LR} 695 TMenu *m; 696 m=new TMenu(); \ 00000002 8820 MOVS R0,#+136 \ 00000004 ........ _BLF `??operator new`,`??operator new??rT` \ 00000008 0400 MOVS R4,R0 \ 0000000A 02D0 BEQ ??xxx_1 \ 0000000C ........ _BLF ??TMenu,??TMenu??rT \ 00000010 00E0 B ??xxx_2 \ ??xxx_1: \ 00000012 0024 MOVS R4,#+0 697 m->Show(2); \ ??xxx_2: \ 00000014 0221 MOVS R1,#+2 \ 00000016 2000 MOVS R0,R4 \ 00000018 ........ _BLF ??Show,??Show??rT 698 delete m; \ 0000001C 2000 MOVS R0,R4 \ 0000001E ........ _BLF `??delete ~TMenu`,`??delete ~TMenu??rT` 699 /*char *s; 700 s=new char[10]; 701 delete [] s;*/ 702 } \ 00000022 10BC POP {R4} \ 00000024 01BC POP {R0} \ 00000026 0047 BX R0 ;; return Возможно, кому-нибудь листинг скажет, что не так... Как-то побороть невозможно. Куда уходит вызов - абсолютно непонятно. В конструкторе класса только одна инструкция (в листинге) - BX LR... Начёт HEAP... Думал тоже, но, как я сказал, malloc() работает. Тоже использует. Грешу чисто на системные библиотеки, даже триальный IAR-5 скачал, не помогло... Дур дом какой-то! Динамическая память нужна везде - если ЖК графический вкинуть, то меню рисовать без объектов очень тоскливо. Кассовые тоже нужны людям, чтоб пользоваться, и когда он достаточно сложен, как у меня, то лучше все-же через меню работать, а не кодами, как по старинке принято.
--------------------
Сомневаюсь, и вам советую!
|
|
|
|
|
Sep 21 2007, 11:13
|
Участник

Группа: Новичок
Сообщений: 21
Регистрация: 13-09-07
Пользователь №: 30 506

|
А в конструкторе что?
|
|
|
|
|
Sep 21 2007, 11:18
|
Участник

Группа: Участник
Сообщений: 63
Регистрация: 21-09-07
Из: СССР
Пользователь №: 30 719

|
Цитата(deadman @ Sep 21 2007, 14:13)  А в конструкторе что? Ничего. Были действия, которые по идее должны экран обновлять, но они не выполнялись. Удалил. Не заработало никак.
--------------------
Сомневаюсь, и вам советую!
|
|
|
|
|
Sep 21 2007, 11:43
|
Участник

Группа: Участник
Сообщений: 63
Регистрация: 21-09-07
Из: СССР
Пользователь №: 30 719

|
У меня тоже нету исходников. А пошагово зайти не могу - симулятор не работает, стопорится на запуске кварца, через j-tag тож не фурычит, да и асм я армовый не очень. Я до этого на 51-м семействе сидел.
--------------------
Сомневаюсь, и вам советую!
|
|
|
|
|
Sep 21 2007, 12:07
|
Участник

Группа: Участник
Сообщений: 63
Регистрация: 21-09-07
Из: СССР
Пользователь №: 30 719

|
J-Link запустил с горем пополам. Короче нашел где ступор - когда вызывает new, заходит в malloc, после чего в abort где и находит бесконечный branch сам на себя.
--------------------
Сомневаюсь, и вам советую!
|
|
|
|
|
Sep 21 2007, 13:21
|
Участник

Группа: Участник
Сообщений: 63
Регистрация: 21-09-07
Из: СССР
Пользователь №: 30 719

|
Цитата(alexander55 @ Sep 21 2007, 15:28)  Ну теперь дело за малым прошагать malloc, а затем понять, что надо что-то поменять в icf файле. В каком файле? Может в .xcl? Так там задано 8000 под HEAP. Статически распределено около 9 кило, 64 всего у камня. После дебага я нашел, что и malloc не работает. Различия лишь в том, что malloc не входит в ступор, а new входит. Похоже, считает, что нет памяти в куче. Осталось найти, где копать. Однако фигово сделано - ни исключений, ничего. Просто бесконечный цикл, без возможности узнать, что памяти нет. Разобрался. По непонятной причине в оболочке писал 8000 хипа, а в файле было 100. Явно не хватало. И при этом все остальные параметры показывает правильно.
--------------------
Сомневаюсь, и вам советую!
|
|
|
|
|
Sep 24 2007, 04:35
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(mungo @ Sep 21 2007, 19:21)  Разобрался. По непонятной причине в оболочке писал 8000 хипа, а в файле было 100. Явно не хватало. И при этом все остальные параметры показывает правильно. По горячим следам. 1. Посмотрел тут ARM® IAR C/C++ Compiler Reference Guide на стр. 13 есть очень короткая глава Dynamic memory on the heap в ней раздел Potential problems. Сказано только как избежать исчерпания кучи, но не сказано, как ведут себя new. Не хорошо как-то... возникло чувство недоделанности не только руководства, но и самого компилятора. Жаль. 2. Ради спортивного интереса открыл к MSDN (MS VC++ 6.0) "If there is insufficient memory for the allocation request, by default operator new returns NULL. You can change this default behavior by writing a custom exception-handling routine and calling the _set_new_handler run-time library function with your function name as its argument." (Перевод мой) "Если для запроса нехватает памяти, то поумолчанию оператор new возвращает NULL. Вы можете изменить такое поведение путем создания своей подпрограммы-обработчика исключения и вызова библиотечной функции _set_new_handler (имеется ввиду из ран-тайм бибиотеки) с именем Вашей функции в качестве аргумента." 2 mungo -- Спасибо за обозначенные грабли. Будем иметь ввиду.
Сообщение отредактировал zhevak - Sep 24 2007, 04:36
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Sep 24 2007, 05:10
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(mungo @ Sep 21 2007, 17:21)  В каком файле? Может в .xcl? Да, в xcl. Я уже зациклился на 5.10 (здесь icf). Насчет куч не обольщайтесь. Они имеют свойство ползти. Старая, старая сказка (Шварц). Еще лет 20 назад все работали под ДОС и ставили резидентов. Было замечено, что после убирания резидентных программ часть свободной памяти как корова языком слизывала. Наше время. До бога молитва дошла, БГ и его банда ввела периодически работающий диспетчер оптимизации свободной памяти. Результаты использования куч. В универсаме кассирша покупателям : "Подождите компьютер перезагружается". (Наблюдаю постоянно). PS. Не все йогурты одинаковы (реклама). Навозну кучу разгребая ... (Крылов) ... не верь глазам своим. (К.Прутков).
|
|
|
|
|
Sep 24 2007, 06:12
|
Частый гость
 
Группа: Новичок
Сообщений: 121
Регистрация: 15-08-06
Пользователь №: 19 557

|
Цитата(zhevak @ Sep 24 2007, 08:35)  Сказано только как избежать исчерпания кучи, но не сказано, как ведут себя new. Не хорошо как-то... возникло чувство недоделанности не только руководства, но и самого компилятора. Жаль. При исчерпании кучи new должен возвращать NULL. Так у всех, поэтому в руководстве про это и не писали. Можно добавить в программу проверку на NULL после new и вывод ошибки. Поможет избежать "загадочного" поведения.
|
|
|
|
|
Sep 24 2007, 06:34
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(Alexey Bishletov @ Sep 24 2007, 12:12)  При исчерпании кучи new должен возвращать NULL. Так у всех, поэтому в руководстве про это и не писали. Можно добавить в программу проверку на NULL после new и вывод ошибки. Поможет избежать "загадочного" поведения. Чуть выше Цитата Короче нашел где ступор - когда вызывает new, заходит в malloc, после чего в abort где и находит бесконечный branch сам на себя. А в самом первом посту Цитата До оператора new все работает, затем просто виснет проц. Я так понял, что new вообще не возвращает управление. Правда, это все со слов автора темы. Что там генерит ИАР-компайлер я не проверял -- нет под руками изделия, где бы можно было проверить отход опрератора new от всемирно принятых правил игры. Добавлять проверку на NULL нужно обязательно!. Для коммерческих программ для компов я это делаю в обязательном порядке, хотя там памяти -- умотаться. Но кто его знает, а вдруг при длительной эксплуатации (несколько недель, месяцев) память исчерпается, и что тогда? Позорный BSOD? А вот для АРМов проврека на NULL -- ну это просто жизненно необходимо!
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Sep 24 2007, 07:51
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(zltigo @ Sep 24 2007, 13:06)  Только перед этом нужно убедится в наличии лифта убедится, что установленный Вами или по умолчанию обработчик исключения по нехватке памяти этот самый NULL возвращает а не делает что-либо другое. Лифт -- О-о, эта аллегория мне нравится  Продолжим нашу священную "религиозную" войну. Я только одного не могу понять. Почему разработчики ИАР-компилятора сделали поведение new несколько отличное от стандарта и при этом никак не удосужились описать его? Может я не там читал? Почему архитекторы спроектировали такуй странный лифт, каждый раз входя в который нужно всегда убеждаться том, что он вообще является лифтом, а не сортиром -- "вошел и провалился". Что до меня, так после таких дел я вообще не хочу пользоваться в ИАРе этим лифтом (new).
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Sep 24 2007, 08:04
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(zhevak @ Sep 24 2007, 10:51)  Я только одного не могу понять. Почему разработчики ИАР-компилятора сделали поведение new несколько отличное от стандарта и при этом никак не удосужились описать его? Может я не там читал? Стандарт читали? Ну и что там вычитали? Там все отдано на откуп программисту. Цитата Почему архитекторы спроектировали такуй странный лифт, каждый раз входя в который нужно всегда убеждаться том, что он вообще является лифтом Архитекторы предоставили прекрасную возможность все гибко настраивать, ибо существует, как минимум, три логичных варианта поведения: - ждать, пока память освободиться в другом процессе и возможно инициализировать процесс освобождения; - повесить общий обработчик этой исключительной ситуации (именно с целью дабы каждый раз не проверять наличия лифта); - возвратить, например, NULL, как это принято в malloc(); Цитата Что до меня, так после таких дел я вообще не хочу пользоваться в ИАРе этим лифтом (new). Я честно говоря не знаю, как он в IAR по умолчанию устроен, но set_new_handler() всегда позволит сделать, то, что Вам надо, да и new(nothrow) поддерживается. Проблемы возникают, только тогда, когда кто-то считает, что new кому-то чего-то должен сделать только по той причине, что так, например, VC++ так сделано.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Sep 24 2007, 08:30
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(Сергей Борщ @ Sep 24 2007, 13:14)  Простой вызов new в случае нехватки памяти вызывает функцию, установленную при помощи set_new_handler(). После чего пытается выделить память снова. В варианте int a= new(nothrow) int[1000]; new при нехватке памяти возвращает 0. Да. Это как раз ожидаемое поведение new. Но, получается, ИАР работает немного по-другому: если обработчик указан -- вызываю, если не указан -- висю. Так?
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Sep 24 2007, 10:34
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(zhevak @ Sep 24 2007, 11:30)  Да. Это как раз ожидаемое поведение new. Но, получается, ИАР работает немного по-другому: если обработчик указан -- вызываю, если не указан -- висю. Так? Нет, получается именно так, как ожидается. Выделяем - памяти нет - вызываем функцию new_handler() (по умолчанию там пустышка) - пытаемся снова выделить память. Поскольку new_handler() ничего не сделал, памяти взяться не откуда, снова получаем "памяти нет" и ку. 2 zltigo: new_handler() возвращает void, поэтому через него нельзя заставить new вернуть 0.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 24 2007, 10:41
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Sep 24 2007, 13:34)  2 zltigo: new_handler() возвращает void, поэтому через него нельзя заставить new вернуть 0. Таки, да  , забыл за давностью лет. Например, одна из реализаций new: Код void *operator new( size_t size ) { void * p; size = size ? size : 1; while ( (p = malloc(size)) == NULL && _new_handler != NULL) _new_handler(); return p; } Патовая ситуация ...
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|