2011-01-18 4 views
1

Я переношу программное обеспечение из Delphi 5 в Delphi XE. Я уже исправил много различий, и теперь я могу скомпилировать свой код.ERangeError on Delphi XE

Проблема в том, что иногда (в некоторых местах кода) я получаю сообщение об ошибке «Ошибка проверки диапазона».

Для Exemple, в этом коде:

function CopyChar(Ori : string; var Des : Array of char) : Boolean; 
var Msg  : string; 
    Counter : integer; 
    SizeDes : integer; 
begin 
    SizeDes:= SizeOf(Des); 
    for Counter:= 1 to SizeDes do begin 
     Des[Counter-1]:= ' '; 
    end; 
    Ori:= Trim(Ori); 
    Msg:= ''; 
    SizeDes:= Min(Length(Ori),SizeDes); 
    for Counter:= 1 to SizeDes do begin 
     Des[Counter-1]:= char(Ori[Counter]); 
    end; 
    CopyChar:= True; 
end; 

я получаю ошибку во время выполнения при прохождении по линии Des [Counter-1]: = ' «; Ошибка возникает не в первый раз, когда она проходит через цикл, но после много раз.

Я попытался отключить Rance Checking ($ R), но он делает nos решает мою проблему. Я также пытался изменить тип «Counter» на Cardinal и LongWord, без успеха

Я был бы рад за любую полезную идею!

Спасибо.

+1

Вместо того, чтобы описывать это как остановку после «много раз», быть точным. Используйте отладчик, чтобы узнать, сколько раз вы проходите через цикл. Это должно было быть одним из первых вещей, которые вы задавали себе сами, когда видели, как он разбился. У всех переменных есть значения, которые вы ожидали от них? Если они этого не делают, как они отличаются? Почему вы ожидали, что у них будут ценности, которые вы сделали, и как они получили другие ценности? –

ответ

5

Код должен читать что-то вроде этого:

function CopyChar(Ori : string; var Des : Array of char) : Boolean; 
var Msg  : string; 
    Counter : integer; 
    LenDes : integer; 
begin 
    LenDes:= Length(Des); 
    for Counter:= 1 to LenDes do begin 
     Des[Counter-1]:= ' '; 
    end; 
    Ori:= Trim(Ori); 
    Msg:= ''; 
    LenDes:= Min(Length(Ori),LenDes); 
    for Counter:= 1 to LenDes do begin 
     Des[Counter-1]:= char(Ori[Counter]); 
    end; 
    CopyChar:= True; 
end; 

Я думаю, ваша проблема связана с Char в настоящее время 2 байта в ширину (в Delphi 5 это 1 байт в ширину), хотя я никогда не использовал SizeOf на открытый массив и даже не знаю, что он делает!

В этом коде есть пара других проблем. Возвращаемое значение кажется немного бессмысленным, поскольку оно может только вернуть True. Это также может быть несколько сжат так:

procedure CopyChar(Ori: string; var Des: array of char); 
var 
    i: Integer; 
begin 
    Ori := Trim(Ori); 
    for i := 1 to Length(Des) do begin 
    if i<=Length(Ori) then 
     Des[i-1] := Ori[i]; 
    else 
     Des[i-1] := ' '; 
    end; 
end; 
+1

Вы не можете использовать динамический массив в приведенном выше коде; Аргумент Des - это статический массив, а SizeOf (Des) = Length (Des) * SizeOf (Char); – kludg

+0

@Serg Моя ошибка, я должен, конечно, написать * открытый массив *, и я исправил это. Фактически вы можете передать динамический массив этой функции. –

+0

Нет, вы не можете передать динамический массив char как открытый массив, по крайней мере, это невозможно в Delphi 2009 - см. Http://stackoverflow.com/questions/3781691/is-a-dynamic-array-of- char-allowed-when-the-parameter-type-is-open-array-of-char – kludg

2

Другая проблема может быть поврежден вход либо Оп или дез, так что если проблема не будет решена путем решения Davids, вы должны проверить код вызова, тоже.

+0

Исходная проблема заключается в том, что SizeOf использовался вместо Length и SizeOf возвращает 2 * Length, когда массив является Char теперь, когда Char имеет ширину 2 байта. И почему это более эффективно? –

+0

Несомненно, но не обязательно единственная проблема. Это более эффективно, потому что сравнение не выполняется для каждой итерации цикла. Это не учитывает то, что делает оптимизатор, признаюсь, что я не читал сгенерированный код сборки;) –

+1

Это вряд ли стоит того, что код становится сложнее читать и проверять! Скорее всего, производительность здесь не будет узким местом. И в любом случае ваш код действительно выполняет сравнение каждой итерации цикла, и он не заканчивается корректно, так как

Смежные вопросы