Page 4 of 4
Re: Open Watcom
Posted: Thu Feb 07, 2008 11:54 pm
by andrew_programmer
Я думаю что твой разрушает кучу malloс
Непонял. Что понимается под фразой,-"твой разрушает". Мой кто? Что ? Я использую malloc из Clib, а не свой собственный.
Одиночные структуры лучше располагать в стеке.
Какие именно структуры ? Что нужно сделать, чтобы они были в стеке ?
P.S.
Извиняюсь за свою дотошность и любопытство.
Re: Open Watcom
Posted: Fri Feb 08, 2008 9:10 am
by Serge
andrew_programmer
Твой код. Я так думаю. Где-то в CreateInterface. Там все структуры создаются malloc хотя это не массивы структур и их можно разместить в стеке. Любая ошибка в работе с указателями может повредить кучу после чего возможны такие трудноуловимые ошибки.
Re: Open Watcom
Posted: Fri Feb 08, 2008 3:42 pm
by andrew_programmer
Твой код. Я так думаю. Где-то в CreateInterface.
Я доработал функцию CreateInterface(). Там сейчас просто нечему разрушать указатели. Единственное из-за чего может сейчас неработать эта функция - неправильное выделение кучи malloc() -ом(если куча до этого разрушена). Даже с новой функцией CreateInterface() перестановка функции LoadSpectra() ведёт всё к тем же последствиям. Значит, если куча и разрушается, то до функции CreateInterface().
Там все структуры создаются malloc хотя это не массивы структур и их можно разместить в стеке.
Насколько я понимаю занесение структуры в стек с нужным выравниванием делается через
#pragma pack(push,number) , где вместо
number выравнивание. Я попробовал это сделать для одной структуры через
#pragma pack(push,1) . Программа работала. А вот когда я такое сделал ещё для другой структуры, то программа стала вылетать. В чём я неправ ?
И ещё вопрос. Если я занёс структуру в стек, то она там будет всё время работы программы? А если вовремя работы программы после использования структуры её нужно удалить из стека, то что делать ? Я думаю, что это как-то делается через
#pragma pack(pop), но вот как - я непонял. Help в OpenWatcom-ме этого не объясняет и Help в MSVC тоже.
Re: Open Watcom
Posted: Fri Feb 08, 2008 5:10 pm
by vectoroc
В стэк сам ты её врядли заносишь, этим занимается компилер, за освобождением он тоже в состоянии сам проследить. Ты наверно не там ошибки ищешь. pop восстанивит выравнивание, дефолтное или которое было до этого (насколько я понимаю)
Re: Open Watcom
Posted: Fri Feb 08, 2008 5:21 pm
by andrew_programmer
стэк сам ты её врядли заносишь, этим занимается компилер,
Я это знаю. Только немогу понять почему у меня код вылетает. Я пробовал ставить
#pragma pack(pop) после структур. Всёравно непомогает.
Подожду ответа
Serge-а. Он всё знает.
Re: Open Watcom
Posted: Fri Feb 08, 2008 5:45 pm
by andrew_programmer
Забыл сказать. Упакованные структуры я объявляю как указатели и при этом не выделяю для них память через malloc.
Re: Open Watcom
Posted: Fri Feb 08, 2008 6:49 pm
by andrew_programmer
Разобрался в чём дело. При сохранении структур в стеке нужно объявлять структуры в программе как переменные и работать с ними соответственно.
Re: Open Watcom
Posted: Sat Feb 09, 2008 2:32 am
by Serge
andrew_programmer
Размещение в стеке - создание локальной переменной. Ты объявляешь указатель на структуру struct ControlButton *ButtonTrueRestore; и потом выделяешь память для неё через malloc а надо сразу создавать экземпляр структуры в стеке struct ControlButton ButtonTrueRestore. Указатель имеет смысл если это будет массив заранее неизвестного размера. Другой пример
char *names_of_bookmarks1[]={"SINGLET","DOUBLET","SIXTET","P(H)","OTHER"};
Этот массив указателей локальный и компилятор честно создаёт его в стеке, копирует туда адреса строк, хотя в этом нет необходимости. Объяви эти массивы static. Это уменьшит размер кода и упростит его. Явных приведений типа лучше избегать. Если InfoForButton.text хранит указатель на строку то пусть это будет char *, а не unsigned int. Ещё одна проблема огромное количество предупреждений при компиляции. Среди них могут быть действительно важные но они просто тонут в общей массе.
Этот код проверяет кучу. У меня всё нормально, значит ошибка в другом месте.
Code: Select all
switch( _heapchk() ) {
case _HEAPOK:
printf( "OK - heap is good\n" );
break;
case _HEAPEMPTY:
printf( "OK - heap is empty\n" );
break;
case _HEAPBADBEGIN:
printf( "ERROR - heap is damaged\n" );
break;
case _HEAPBADNODE:
printf( "ERROR - bad node in heap\n" );
break;
}
Re: Open Watcom
Posted: Sat Feb 09, 2008 1:32 pm
by andrew_programmer
Serge
Спасибо за советы.
Ты объявляешь указатель на структуру struct ControlButton *ButtonTrueRestore; и потом выделяешь память для неё через malloc а надо сразу создавать экземпляр структуры в стеке struct ControlButton ButtonTrueRestore. Указатель имеет смысл если это будет массив заранее неизвестного размера.
Я так и сделал вчера - работает.
Другой пример
char *names_of_bookmarks1[]={"SINGLET","DOUBLET","SIXTET","P(H)","OTHER"};
Этот массив указателей локальный и компилятор честно создаёт его в стеке, копирует туда адреса строк, хотя в этом нет необходимости. Объяви эти массивы static. Это уменьшит размер кода и упростит его.
Сделаю.
Ещё одна проблема огромное количество предупреждений при компиляции. Среди них могут быть действительно важные но они просто тонут в общей массе.
При самой первой компиляции их было в разы больше. Но я просмотрел
каждое сообщение компилятора. И оставил только те, которые неважны(типа "ненайден прототип для функции"). Там ещё есть сообщения про переопределения функций libGUI, но как сделать, чтобы он правильно понял идею - непонятно. Но главное, что код с функциями libGUI работает как и должно работать.
Этот код проверяет кучу. У меня всё нормально, значит ошибка в другом месте.
Только вот в каком другом... Но я всётаки хочу добить эту проблему.
Мне хочется сделать OpenWatcom основным инструментом для разработки научных программ для KolibriOS. Тем более что, как показывают тесты, моя научная программа, скомпилированная Watcom-ом работает на 40% быстрее, чем скомпилированная GCC. Причём в варианте с GCC уже первый уровень оптимизации приводит к неработоспособности программы, а у OpenWatcom-а с этим всё впорядке.
Re: Open Watcom
Posted: Sat Feb 09, 2008 5:05 pm
by andrew_programmer
Serge
Ха!
Не там собака была зарыта, где её искали! (поговорка)
Я нашёл истинную причину!
И так, как было дело.
Я почистил код программы, так что компилятору просто не к чему было придраться. А код всёравно глючил. Проблема возникала при открытии файла для сохранения результатов вычислений. Причём результаты вычислений P(H) сохрнялись(там открывалось 2 файла), а результаты дискретной обработки нет(там один файл открывался).
Уменя компиляция происходила с опцией "fastest possible cod" , а под стек выделялось 10Kb. Я решил скомпилировать код вообще без оптимизации. Скомпилировал. Попробовал вычислить программой P(H) - работает. Попробывал обработать дискретный спектр - вылетает уже на этапе старта алгоритма. И при этом на доске отладки появляется сообщение "stack overflow"(переполнение стека). Я выделил под стек 16 Kb -мало. Выделил 64Kb -
код заработал без ошибок(нет глюков!).
Большое спасибо за советы!
Теперь можно по нормальному программировать.
Re: Open Watcom
Posted: Sat Mar 01, 2008 1:40 am
by SHREDER
andrew_programmer wrote:Разобрался в чём дело. При сохранении структур в стеке нужно объявлять структуры в программе как переменные и работать с ними соответственно.
Обычный прикол С
struct A {
int a;
int b;
};
struct A a;
struct A b;
A *p = (A*)malloc(sizeof(A));
free(p);
return 0;
При создании переменной в стеке нужно указывать слово struct. Это в плюсах можно этого не делать
а в си будет плохо.