Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разбил процедуру на две. В результате - ошибка! 
:(
    Опции темы
overall
Дата 17.6.2007, 05:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 17.6.2007

Репутация: нет
Всего: нет



Здравствуйте. Вот такая вот фигня у меня. Уже третий день сижу мучаюсь не могу понять, где что не так.

Была процедура следующего вида:

Весь код не привожу, больно большой.

Код

procedure ReadItemsTo(...);
var
  I: Integer;
begin
  for I := 0 to ... do
  begin
    //Кусок кода #1
  end;
end;


Разбил её на две, путем выноса из под цикла:

Код


function ReadItem(...): ...;
begin
  //Кусок кода #1
end;

procedure ReadItemsTo(...);
var
  I: Integer;
begin
  for I := 0 to ... do
  begin
    ... := ReadItem(...);
  end;
end;


Вынес правильно.

В старой версии процедура рекурсивно вызывала саму себя.
После разбивки соответственно рекурсия сохранилась, но опосредованно (ReadItemsTo -> ReadItem -> ReadItemsTo -> ReadItem -> ...).

Компилится и работает, но в некоторых случаях
возникает AV (Access Violation) в процедуре "DeleteFree()" в "getmem.inc" (системный модуль).

Код

procedure DeleteFree(f: PFree);
var
  n, p: PFree;
  size: Integer;
begin
  if rover = f then
    rover := f.next;
  n := f.next;
  size := f.size;
  if size <= cSmallSize then begin
    if n = f then
      smallTab[size div cAlign] := nil
    else begin
      smallTab[size div cAlign] := n;
      p := f.prev;
      n.prev := p;
      p.next := n;
    end;
  end else begin
    p := f.prev;
    n.prev := p; // Здесь!!!
    p.next := n;
  end;
end;



Всё это определенно очень странно.
До разбития процедуры всё работало отлично без таких вот выкрутасов.
Может это баг компилятора? (Пробовал и на Delphi 5 и на Delphi 6 - и там и там таже самая ошибка)

Думаю, может что-то не так с выделением памяти, раз ошибка в DeleteFree (процедура стандартного менеджера памяти).
Руками память не выделяю. Только создание и уничтожение объектов, ну и строки (длинные).
Но если дело с памятью, то почему тогда всё отлично работает, когда процедура не разбита? Не понимаю...

Подскажите, что-нибудь, пожалуйста!

Это сообщение отредактировал(а) Alexeis - 17.6.2007, 12:01
PM MAIL   Вверх
aktuba
Дата 17.6.2007, 05:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 7
Всего: 38



Скорее всего дело именно в рекурсии. Но что-бы сказать что-то определенное - надо смотреть весь код...


--------------------
user posted image
PM MAIL WWW Skype   Вверх
Sunvas
Дата 17.6.2007, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Соль и сахар
****


Профиль
Группа: Участник
Сообщений: 3388
Регистрация: 12.3.2006
Где: Тосно

Репутация: 2
Всего: 89



Порой действительно встречаються артефакты. Но, как уже было сказано - весь код в студию!


--------------------
Воспитывая детей по своему образу и подобию, родители почему-то надеются, что они будут лучше их.
PM MAIL   Вверх
overall
Дата 18.6.2007, 04:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 17.6.2007

Репутация: нет
Всего: нет



Разобрался сам.

Это был баг компилятора Delphi.

Смотреть ассемблерный код не стал, разбираться что да почему.

Код

  procedure ReadItemsTo(ARuleItemList: TRuleItemList; const APrefix: string);
  var
    ItemCount: Integer;
    I: Integer;
    ItemPrefix: string;

    RuleItem: TRuleItem;
  begin
    ItemCount := ...;

    for I := 0 to ItemCount - 1 do
    begin
      ItemPrefix := APrefix + ...;

      RuleItem := ReadItem(ItemPrefix);

      ARuleItemList.Add(RuleItem);
    end;
  end;

  function ReadItem(const APrefix: string): TRuleItem;
  var
    ItemPrefix: string;
    RuleItem: TRuleItem;
    ...
  begin
    RuleItem := nil;

    ItemPrefix := APrefix;

    // А здесь интенсивно ипользуется ItemPrefix
    ...

    Result := RuleItem;
  end;


Так вот из-за присвоения:

ItemPrefix := APrefix;

вся фигня и была.

Дело в том, что параметр APrefix больше нигде не используется в этой процедуре.
И видимо компилятор не производил никакого присваивания, а как-то
с оптимизировал код, что просто APrefix "стал" ItemPrefix, но сделал это неправильно.

После того, как переписал процедуру вот так:

Код

  function ReadItem(const APrefix: string): TRuleItem;
  var
    RuleItem: TRuleItem;
    ...
  begin
    RuleItem := nil;

    // А здесь интенсивно ипользуется APrefix
    ...

    Result := RuleItem;
  end;


никаких багов нет и GetHeapStatus не возвращает ошибки.


В компиляторе Delphi 6 есть так же баг с переполнением стека FPU, размер которого 8 элементов.
И при вычислении БОЛЬШОГО выражения с вещественными числами (на практике такие выражения встречаются наверное почти никогда),
приводит к исключению, а именно к переполнению стека FPU. Они уж хотя бы проверку в компилятор добавили бы,
что мол выражение слишком большое - переформулируйте.
PM MAIL   Вверх
aktuba
Дата 18.6.2007, 06:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 7
Всего: 38



Цитата

Это был баг компилятора Delphi.


Мдя... Смахивает на параною...

Цитата

ItemPrefix := APrefix;


Хочешь сказать, у всех компилятор умеет присваивать строки, а у тебя разучился??? =))))
Ну если сам веришь в это - вперед. Но ... smile 


--------------------
user posted image
PM MAIL WWW Skype   Вверх
delphi_
Дата 18.6.2007, 08:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 140
Регистрация: 30.11.2006

Репутация: нет
Всего: -1



это не баг это фича
отключи оптимизацию smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0712 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.