|
Вопрос # 4 218/ вопрос открыт / |
|
Приветствую, уважаемые эксперты!
используется TurboDelphi, создан класс:
type
TVarRes = record
Style : Integer;
NameVar : String;
end;
TListEdit = class(TCustomControl)
private
Vars : TStringList;
public
function GetParam(idx: integer): TVarRes;
....
end;
function TListEdit.GetParam(idx: integer): TVarRes;
var
p : TPanelEdit;
begin
p := TPanelEdit(Vars.Objects[idx]);
Result.Style := p.Style;
------------------------------------------------
ошибка исполнения в этой строке
Result.NameVar := Vars.Strings[idx];
------------------------------------------------
end;
исключение возникает в _LStrAsg (System.pas) - где указан комментарий об использовании глобальных и локальных переменных.
Голова отказывается понимать в чем проблема... на всякий случай пробовал переименовать переменные и создать в функции дополнительную переменную TVarRes - не помогло.
в чем может быть проблема появления исключения?
так-же замечу что класс разрабатывался 2 месяца назад и на этапе разработки класс успешно работал.
 |
Вопрос задал: Тарасов Андрей (статус: Посетитель)
Вопрос отправлен: 24 мая 2010, 11:03
Состояние вопроса: открыт, ответов: 0.
|
Мини-форум вопроса
Всего сообщений: 10; последнее сообщение — 24 мая 2010, 13:32; участников в обсуждении: 2.
|
Вадим К (статус: Академик), 24 мая 2010, 11:42 [#1]:
Кажется Вы выложили не совсем полные исходники. Вот пишете Цитата (Тарасов Андрей):
ошибка исполнения в этой строке
Result.NameVar := Vars.Strings[idx];
А где же код, который вызывает эту строку?
Хотя кажется я знаю, где ошибка,но нужно увидеть больше сорцов.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Тарасов Андрей (статус: Посетитель), 24 мая 2010, 11:57 [#2]:
не понял зачем, но вот вызов
var
st: TVarRes;
begin
{тут собственно в цикле вызов,
ошибка при первом вызове - например так}
st := ListEdit.GetParam(0);
внутри класса функция не вызывается
|
|
Вадим К (статус: Академик), 24 мая 2010, 12:00 [#3]:
А покажите код, который складывает все это в TListEdit.
Код нужно показывать - тут не телепаты, они иногда конечно угадывают, но не всегда.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Тарасов Андрей (статус: Посетитель), 24 мая 2010, 12:23 [#5]:
ну если интересна предистория - то вот (с детализацией)
------------------------------------------------
это происходит раньше
ListParam : TStringList;
ListParam.Add('Начальная дата=D_START=Дата');
ListParam.Add('Конечная дата=D_END=Дата');
DataSet.FieldByName('PAR_SQL').AsString := ListParam.Text;
-------------------------------------------------
так происходит присвоение
ListEdit.SetLines( DataSet.FieldByName('PAR_SQL').AsString );
-------------------------------------------------
реализация
// в классе рядом с Vars есть
List : TStringList;
procedure TListEdit.SetLines(data: String);
var
i : integer;
p : TPanelEdit;
s : TStringList;
begin
s := TStringList.Create();
List.Text := data;
for I := 0 to List.Count - 1 do
begin
p := TPanelEdit.Create(self);
p.Parent := self;
p.SetLabel(List.Names[i]);
List.Objects[i] := p;
s.Add(List.Values[List.Names[i]]);
end;
for I := 0 to List.Count - 1 do
begin
p := TPanelEdit(List.Objects[i]);
p.SetData(s.Values[s.Names[i]]);
Vars.AddObject( s.Names[i], p );
end;
s.Free;
CountVar := List.Count;
end;
|
|
Вадим К (статус: Академик), 24 мая 2010, 12:27 [#6]:
первая ошибка скорее всего тут
for idx:=0 to rc do
должно быть
for idx:=0 to rc-1 do
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Тарасов Андрей (статус: Посетитель), 24 мая 2010, 12:41 [#7]:
да конечно - неудачно поправил после копипаста....
но я так понимаю что-то связано 0(нулевым) элементом массива
и этот косяк как-то связан с линковкой, предварительный вызов следующего элемента привел к "нормальной" работе компонента...
|
|
Вадим К (статус: Академик), 24 мая 2010, 12:49 [#8]:
тут не линковка виновата, и не компилятор. Если происходит обращание к несуществующему элементу, то что же поделать.
Рекомендую в функции function GetParam(idx: integer): TVarRes;
вставить доп проверку на индекс.
Так код заработал после этого исправления?
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Тарасов Андрей (статус: Посетитель), 24 мая 2010, 13:14 [#9]:
в функции, где возникает исключение пишут следующее:
_LStrAsg
This function is used when assigning to global variables.
Literals are copied to prevent a situation where a dynamically
allocated DLL or package assigns a literal to a variable and then
is unloaded -- thereby causing the string memory (in the code
segment of the DLL) to be removed -- and therefore leaving the
global variable pointing to invalid memory.
шайтан какой-то, а сейчас код заработал после принудительного вызова ПЕРВОГО элемента в списке
вот так пока оставил
st := ListEdit.GetParam(0);
st := ListEdit.GetParam(idx);
и конечный результат выдается правильно...
будет время - попробую сам разобраться
|
|
Вадим К (статус: Академик), 24 мая 2010, 13:32 [#10]:
Если говорить простым языком, то эта функция "компиляторная"
То есть, когда пишем
s := "str",
компилятор вставляет вызов этой функции.
Но представьте себе, что ей был передан несуществующий адрес или нулевой. И конечно будет ошибка. И ошибка не в ней, а где то в другом месте.
Итого, нужно искать, где был доступ к несуществующей памяти.
Галочка "подтверждения прочтения" - вселенское зло.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|