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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Invalid pointer operation 
V
    Опции темы
seroga87
Дата 25.10.2009, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Добрый вечер! Задача такова - имеется массив такого вида:
Цитата

1    1    0
2    2    1
3    3    2
  ...
36    36    35
37    37    36
38    38    37
39    39    38
40    39а    39
41    40    39а
42    40а    40
43    41    40а
44    42    41
  ...    

Его нужно будет сортитровать так, чтобы во 2м и 3м столбиках значения шли в таком порядке как показано. То есть например: 1 затем 1а затем 1б. Для сортировки нужно написать DLLку. Большая часть кода из нее представлена ниже. В DLL есть 3 процедуры SetArray, Sort и GetArray. Ошибка Invalid pointer operation выскакивает после вызова из EXE процедуры GetArray, при чем значения выводятся до конца, цикл завершается и после этого вылазит ошибка. Если закоментировать в процедуре Sort вот так 
Код

arr[i][1]:=IntTostr(b[i][0]){+chr(b[i][1])}
arr[i][2]:=IntTostr(b[i][2]){+chr(b[i][3])}
, то ошибка пропадает. Так же ошибка пропадает если не вызывать из EXE процедуру Sort, или если не вызывать только GetArray. Подскажите причину появления такой ошибки.
        
Часть кода DLL:

Код

procedure SetArray (A:PChar;B:PChar;C:PChar;index:integer);stdcall;
var i:integer;
begin
size:=i+1;
SetLength(arr,size,3);

arr[i][0]:=A;
arr[i][1]:=B;
arr[i][2]:=C;
end;

procedure Sort;stdcall;
var
   b:array of array of integer; //ìàññèâ äëÿ ñîðòèðîâêè
   k,j:integer;       // òåêóùèé ýëåìåíò ìàññèâà
   i:integer;       // èíäåêñ äëÿ ââîäà è âûâîäà ìàññèâà
   changed:boolean; // TRUE, åñëè â òåêóùåì öèêëå áûëè îáìåíû
   buf:integer;     // áóôåð äëÿ îáìåíà ýëåìåíòîâ ìàññèâà

//...
//... здесь массив b сортируется
//...

   for i:=0 to SIZE do
   begin
        if b[i][1]<>0 then
              arr[i][1]:=IntTostr(b[i][0])+chr(b[i][1])
        else
              arr[i][1]:=IntTostr(b[i][0]);

        if b[i][3]<>0 then
              arr[i][2]:=IntTostr(b[i][2])+chr(b[i][3])
        else
              arr[i][2]:=IntTostr(b[i][2]);

        arr[i][0]:=IntToStr(i+1);
   end;

end;

procedure GetArray(A:PChar;B:PChar;C:PChar;index:integer);stdcall;
var i:integer;
    StrData1:Longword absolute A;
    StrData2:Longword absolute B;
    StrData3:Longword absolute C;
    StrDataSizePtr:^Longword;
begin
  StrPLCopy(A,arr[i][0],length(arr[i][0]));
  StrPLCopy(B,arr[i][1],length(arr[i][1]));
  StrPLCopy(C,arr[i][2],length(arr[i][2]));

  StrDataSizePtr:=Ptr(StrData1-4);
  StrDataSizePtr^:=Length(arr[i][0]);
  StrDataSizePtr:=Ptr(StrData2-4);
  StrDataSizePtr^:=Length(arr[i][1]);
  StrDataSizePtr:=Ptr(StrData3-4);
  StrDataSizePtr^:=Length(arr[i][2]);

end;

exports
  SetArray name 'SetArray',
  Sort name 'Sort',
  GetArray name 'GetArray';

begin
end.


Код EXE:

Код

procedure SetArray (A:PChar;B:PChar;C:PChar;index:integer);stdcall; external 'srt.dll';
procedure Sort;stdcall; external 'srt.dll';
procedure GetArray(A:PChar;B:PChar;C:PChar;index:integer);stdcall; external 'srt.dll';

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var i,tr,size:integer;
    arr:array of array of string;
begin
Memo1.Lines.Clear;
Memo2.Lines.Clear;
randomize;
size:=SpinEdit1.Value;
SetLength(arr,size,3);
for i:=0 to size-1 do
begin
  arr[i][0]:='0';
    arr[i][1]:=inttostr(random(900));
  arr[i][2]:=inttostr(random(900));
    tr:=random(8);
    if (tr>=5) and (tr<7) then
    begin
        arr[i][1]:=arr[i][1]+char(192);
    arr[i][2]:=arr[i][2]+char(192);
    end;
    if tr>=7 then
    begin
        arr[i][1]:=arr[i][1]+char(193);
    arr[i][2]:=arr[i][2]+char(193);
    end;
end;

for i:=0 to size-1 do
  begin
  Memo1.Lines.Add(arr[i][0]+#9+arr[i][1]+#9+arr[i][2]);
  SetArray(Pchar(arr[i][0]),Pchar(arr[i][1]),Pchar(arr[i][2]),i);
  end;


Sort;

for i:=0 to size-1 do
  begin
  GetArray(pchar(arr[i][0]),pchar(arr[i][1]),pchar(arr[i][2]),i);
  Memo2.Lines.Add(arr[i][0]+#9+arr[i][1]+#9+arr[i][2]);
  end;

end;

end.


Это сообщение отредактировал(а) seroga87 - 25.10.2009, 19:25
PM ICQ   Вверх
Hexel
Дата 25.10.2009, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



процедура SetArray
Код

size:=i+1;

наверное, ты имел ввиду
Код

size:=index+1;


и вообще плохо в такой задаче использовать глобальные переменные. твой size можно определять и "по горячему"
Код

size := Length(arr);


далее...
Код

//...
//... здесь массив b сортируется
//...

   for i:=0 to SIZE do


если я правильно понимаю значение переменной SIZE, то
Код

for i:=0 to SIZE - 1 do


и опять же
Код

procedure GetArray(A:PChar;B:PChar;C:PChar;index:integer);stdcall;
  ...
  StrPLCopy(A,arr[i][0],length(arr[i][0]));
  ...

неизвестно, откуда берется переменная i

в проге не присматривался, но вроде верно

Добавлено через 1 минуту и 30 секунд
тебя компилятор сто пудов предупреждал о таких подводных камнях
PM MAIL   Вверх
seroga87
Дата 25.10.2009, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



size - это размер динамического массива, увеличивается по мере поступления элементов из программы. По поводу отнимания единицы от size уже перепроверял, все точно, просто если бы переменная была на 1-цу больше была бы ошибка access violation, меньше где-то бы "вылезла" бы "недописаная" строчка.
С переменными i я прохлопал, хотя и в этом виде выдавался нужный результат, так как они работали аналогично счетчику цикла.
PM ICQ   Вверх
Hexel
Дата 25.10.2009, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(seroga87 @  25.10.2009,  21:43 Найти цитируемый пост)
если бы переменная была на 1-цу больше была бы ошибка access violation


аккуратней с этим. ошибка access violation выскакивает не всегда, особенно для динамических массивов. а партачит именно в момент выгрузки, по выходу из процедуры
PM MAIL   Вверх
seroga87
Дата 27.10.2009, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вобщем проблема решена. Все дело было в размере строки которая передавалась через параметр A,B,C, то есть в некоторых случаях она была короче чем нужно. Переписал наново GetArray
Код
function GetArray(const Buf:PChar;i,j:cardinal;var BufSize:cardinal):boolean;stdcall;
var size:cardinal;
begin
    size:=Length(arr[i][j]);

    if Buf = nil then
    begin
      Result := False;
      Exit;
    end;

    if (BufSize < size) or (BufSize > size) then
    begin
      Result := False;
      BufSize:=size;
      Exit;
    end
    else
    begin
      Result := True;
      StrPLCopy(Buf, PChar(arr[i][j]), size);
    end;

end; 


в exe теперь так:
Код
for i:=0 to size-1 do
  begin
    for j:=0 to 2 do
    begin
      size:=length(arr[i][j]);
      if GetArray(pchar(arr[i][j]),i,j,size)=False then
      begin
        SetLength(arr[i][j],size);
        GetArray(pchar(arr[i][j]),i,j,size);
      end;
    end;
  Memo2.Lines.Add(arr[i][0]+#9+arr[i][1]+#9+arr[i][2]);
  end;


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

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

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

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

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


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

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


 




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


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

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