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

Ха!
Не там собака была зарыта, где её искали! (поговорка)
Я нашёл истинную причину! :D :D :D

И так, как было дело.
Я почистил код программы, так что компилятору просто не к чему было придраться. А код всёравно глючил. Проблема возникала при открытии файла для сохранения результатов вычислений. Причём результаты вычислений 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. Это в плюсах можно этого не делать :) а в си будет плохо.