реклама на сайте
подробности

 
 
> IAR 4.41A & C++
mungo
сообщение Sep 21 2007, 08:13
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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() работает.
help.gif


--------------------
Сомневаюсь, и вам советую!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
mungo
сообщение Sep 21 2007, 12:07
Сообщение #2


Участник
*

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



J-Link запустил с горем пополам. Короче нашел где ступор - когда вызывает new, заходит в malloc, после чего в abort где и находит бесконечный branch сам на себя.


--------------------
Сомневаюсь, и вам советую!
Go to the top of the page
 
+Quote Post
alexander55
сообщение Sep 21 2007, 12:28
Сообщение #3


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(mungo @ Sep 21 2007, 16:07) *
J-Link запустил с горем пополам. Короче нашел где ступор - когда вызывает new, заходит в malloc, после чего в abort где и находит бесконечный branch сам на себя.

Ну теперь дело за малым прошагать malloc, а затем понять, что надо что-то поменять в icf файле.
Go to the top of the page
 
+Quote Post
mungo
сообщение Sep 21 2007, 13:21
Сообщение #4


Участник
*

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



Цитата(alexander55 @ Sep 21 2007, 15:28) *
Ну теперь дело за малым прошагать malloc, а затем понять, что надо что-то поменять в icf файле.


В каком файле? Может в .xcl? Так там задано 8000 под HEAP. Статически распределено около 9 кило, 64 всего у камня.

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

Разобрался. По непонятной причине в оболочке писал 8000 хипа, а в файле было 100. Явно не хватало. И при этом все остальные параметры показывает правильно.


--------------------
Сомневаюсь, и вам советую!
Go to the top of the page
 
+Quote Post
zhevak
сообщение Sep 24 2007, 04:35
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 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


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
Alexey Bishletov
сообщение Sep 24 2007, 06:12
Сообщение #6


Частый гость
**

Группа: Новичок
Сообщений: 121
Регистрация: 15-08-06
Пользователь №: 19 557



Цитата(zhevak @ Sep 24 2007, 08:35) *
Сказано только как избежать исчерпания кучи, но не сказано, как ведут себя new. Не хорошо как-то... возникло чувство недоделанности не только руководства, но и самого компилятора. Жаль.

При исчерпании кучи new должен возвращать NULL. Так у всех, поэтому в руководстве про это и не писали. Можно добавить в программу проверку на NULL после new и вывод ошибки. Поможет избежать "загадочного" поведения.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 24 2007, 06:29
Сообщение #7


Гуру
******

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



Цитата(Alexey Bishletov @ Sep 24 2007, 09:12) *
При исчерпании кучи new должен возвращать NULL.

Это malloc() должен, а new, за просто так, никому ничего не должен.
Читаем здесь http://electronix.ru/forum/index.php?showt...hl=new&st=0


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
alexander55
сообщение Sep 24 2007, 07:02
Сообщение #8


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Я завелся (значит не прав), но проделал полезную работу в рамках тестирования IAR 5.10.
Привожу тексты.
Это тестовые классы.
#ifndef Class_TestH
#define Class_TestH

void Test_Classes(void);

// проверка С++ 5.10

class TZero {
protected:
unsigned char var_char;
public:
TZero(void) {var_char=0; cout << "Created class TZero\n";};
~TZero(){cout<<"Delete TZero\n";};
void Show(void) { cout <<"var_char=" << (int)var_char <<"\n";};
};

class TOne : public TZero
{
protected:
unsigned short var_short;
unsigned int var_int;
public:
TOne(void) {var_char=5;};
TOne (char i) {
var_char=i;
var_short=0; var_int=0;
cout << "Created class TOne" << (int)var_char << "\n";
};
~TOne(){cout<<"Delete TOne\n";};
void Show(void) {
cout << "var_char="<< (int)var_char <<" var_short="\
<<var_short <<" var_int="<<var_int <<"\n";
};
void Inc_Short(void) {var_short++;};
void Inc_Int(void) {var_int++;};
};

class TAdd {
public:
TAdd(void) {cout << "Created TAdd\n";};
~TAdd(){cout<<"Delete TAdd\n";};
};

class TTwo : public TOne, public TAdd
{
public:
TTwo (void) { cout << "Created class TTwo" << "\n";};
~TTwo(){cout<<"Delete TTwo\n";};
void Show(void) {
cout << "var_char="<< (int)var_char <<" var_short="<<var_short\
<<" var_int="<<var_int <<"\n";
};
};
//------------------------------------------------------------------------
//#define Variant
void Test_Classes(void) {
#ifdef Variant
TZero *ptr_0=new TZero();
TOne *ptr_1=new TOne(1);
TOne *ptr_2=new TOne(2);
TTwo *ptr_3=new TTwo();
ptr_1->Inc_Short();
ptr_2->Inc_Int();
ptr_0->Show(); //TZero
ptr_1->Show(); //TZero>TOne
ptr_2->Show(); //TZero>TOne
ptr_3->Show(); //TZero>TOne+TAdd >TTwo
cout<<"ptr_0="<<ptr_0 \
<<" ptr_1="<<ptr_1 \
<<" ptr_2="<<ptr_2 \
<<" ptr_3="<<ptr_3 <<"\n";
delete ptr_2;
delete ptr_1;
delete ptr_0;
delete ptr_3;
#else
TZero Zero;
TZero *ptr_0=&Zero;
TOne One1(1);
TOne *ptr_1=&One1;
TOne One2(2);
TOne *ptr_2=&One2;
TTwo Two;
TTwo *ptr_3=&Two;

ptr_1->Inc_Short();
ptr_2->Inc_Int();
ptr_0->Show(); //TZero
ptr_1->Show(); //TZero<TOne
ptr_2->Show(); //TZero<TOne
ptr_3->Show(); //TZero<TOne+TAdd <TTwo
cout<<"ptr_0="<<ptr_0 \
<<" ptr_1="<<ptr_1 \
<<" ptr_2="<<ptr_2 \
<<" ptr_3="<<ptr_3 <<"\n"\
<<" SizeOf Zero="<<sizeof(Zero) <<"\n"\
<<" SizeOf One1="<<sizeof(One1) <<"\n"\
<<" SizeOf One2="<<sizeof(One2) <<"\n"\
<<" SizeOf Two="<<sizeof(Two) <<"\n";
#endif
}

#endif
и кусок main тестирующий
//---------
while (TRUE) {
Test_Classes();
for(unsigned int a=0;a<0x100000;a++);
}
}
Результаты: ptr не ползут нигде.

Created class TZero
Created class TOne1
Created class TZero
Created class TOne2
Created class TZero
Created TAdd
Created class TTwo
var_char=0
var_char=1 var_short=1 var_int=0
var_char=2 var_short=0 var_int=1
var_char=5 var_short=0 var_int=1073763204
ptr_0=40001fc0 ptr_1=40001fd4 ptr_2=40001fcc ptr_3=40001fc4
SizeOf Zero=1
SizeOf One1=8
SizeOf One2=8
SizeOf Two=8
Delete TTwo
Delete TAdd
Delete TOne
Delete TZero
Delete TOne
Delete TZero
Delete TOne
Delete TZero
Delete TZero
и т.д.

Created class TZero
Created class TZero
Created class TOne1
Created class TZero
Created class TOne2
Created class TZero
Created TAdd
Created class TTwo
var_char=0
var_char=1 var_short=1 var_int=0
var_char=2 var_short=0 var_int=1
var_char=5 var_short=0 var_int=0
ptr_0=40002068 ptr_1=40002078 ptr_2=40002088 ptr_3=40002098
Delete TOne
Delete TZero
Delete TOne
Delete TZero
Delete TZero
Delete TTwo
Delete TAdd
Delete TOne
Delete TZero
и т.д.

PS. Я менял delete местами - не придраться, все ОК.
Все логично. P.J.P. молодец.
Но к кучам я все равно отношусь с недоверием.
Да, множественное наследование работает в eec++
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- mungo   IAR 4.41A & C++   Sep 21 2007, 08:13
- - alexander55   Цитата(mungo @ Sep 21 2007, 12:13) TMenu ...   Sep 21 2007, 09:28
|- - mungo   Цитата(alexander55 @ Sep 21 2007, 12:28) ...   Sep 21 2007, 09:52
|- - jorikdima   Цитата(alexander55 @ Sep 21 2007, 13:28) ...   Sep 21 2007, 10:03
|- - mungo   Цитата(jorikdima @ Sep 21 2007, 13:03) Кр...   Sep 21 2007, 10:12
|- - zhevak   Цитата(mungo @ Sep 21 2007, 16:12) Да, пр...   Sep 21 2007, 10:37
|- - alexander55   Цитата(mungo @ Sep 21 2007, 14:12) Да, пр...   Sep 21 2007, 10:41
- - mungo   Код 693 void xxx() 694 { \ ...   Sep 21 2007, 10:58
- - deadman   А в конструкторе что?   Sep 21 2007, 11:13
|- - mungo   Цитата(deadman @ Sep 21 2007, 14:13) А в ...   Sep 21 2007, 11:18
|- - Alexey Bishletov   Видимо new и malloc все же различаются в части выд...   Sep 21 2007, 11:38
- - mungo   У меня тоже нету исходников. А пошагово зайти не м...   Sep 21 2007, 11:43
- - Alechek   Чтобы не стопорился, вызвать функцию до SysInit() ...   Sep 21 2007, 11:57
|- - zhevak   Цитата(Alexey Bishletov @ Sep 24 2007, 12...   Sep 24 2007, 06:34
|- - zltigo   Цитата(zhevak @ Sep 24 2007, 09:34) Добав...   Sep 24 2007, 07:06
||- - zhevak   Цитата(zltigo @ Sep 24 2007, 13:06) Тольк...   Sep 24 2007, 07:51
||- - alexander55   Цитата(zhevak @ Sep 24 2007, 11:51) я воо...   Sep 24 2007, 08:02
||- - zltigo   Цитата(zhevak @ Sep 24 2007, 10:51) Я тол...   Sep 24 2007, 08:04
|- - Сергей Борщ   Цитата(zhevak @ Sep 24 2007, 09:34) Я так...   Sep 24 2007, 07:14
|- - zhevak   Цитата(Сергей Борщ @ Sep 24 2007, 13:14) ...   Sep 24 2007, 08:30
|- - zltigo   Цитата(zhevak @ Sep 24 2007, 11:30) Да. Э...   Sep 24 2007, 08:41
|- - Сергей Борщ   Цитата(zhevak @ Sep 24 2007, 11:30) Да. Э...   Sep 24 2007, 10:34
|- - zltigo   Цитата(Сергей Борщ @ Sep 24 2007, 13:34) ...   Sep 24 2007, 10:41
- - alexander55   Цитата(mungo @ Sep 21 2007, 17:21) В како...   Sep 24 2007, 05:10


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 23:33
Рейтинг@Mail.ru


Страница сгенерированна за 0.01468 секунд с 7
ELECTRONIX ©2004-2016