dinamic array + library

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Saemon Zixel
новенький
Сообщения: 78
Зарегистрирован: 20.09.2005 18:19:54
Откуда: Sochi

Сообщение Saemon Zixel »

Всплыла проблема:
У библеотеки каторую я пишу есть динамический массив с записями. Мая прога, каторая подключает эту библеотеку, в цикле вызывает процедуру в библеотеке с данными для добавления, библеотека если надо увеличивает размер массива и добавляет новый элемент...

Код: Выделить всё

//----------------------- Либа ------------------------
library mylib;
type
  TwoInt = record
      one,two: integer;
   end;
var myarr: array of TwoInt;
       myarrCount: integer;

procedure AddItem(num, a1, a2: integer); cdecl;
begin
   if myarrCount<num then begin
      myarrCount:=num+1;
      SetLength(myarr,myarrCount);
   end;
  myarr[num].one:=a1;
  myarr[num].two:=a2;
end;

function GetItem1(num): integer; cdecl;
begin return:=myarr(num).one; end;

exports AddItem, GetItem;
end.
//-------------------------- Прога ---------------------------------
program test;

procedure AddItem(num, a1, a2: integer); cdecl; external 'libmylib.so';
function GetItem1(num): integer; cdecl; external 'libmylib.so';

var i: integr;
begin
//сдесь мы запалняем его данными, например
 for i:= 0 to 50 do AddItem(i,i+1,i-2);
//сдесь идёт тело проги и куча вызовов функций и проц. из библеотеки например
 for i:= 0 to 50 do GetItem1(i);
 ... и разные другие (каторые не делают SetLength) ...
// и вдруг нам приспичило добавить
 for i:= 51 to 60 do AddItem(i,i+1,i-2);
end.


Когда в начяле запалняется массив то всё нормально, но при попытки позже добавить то выскакивает сообщение об ошибке:
SYSTEM_REMOVE_FROM_LIST_VAR$PMEMCHUNK_VAR
Ну и строчка указывает на SetLength в библеотеке. Номер ошибки 216.
Но что прикольно, при просмотре CallStack то 2 элемента он всёже добовляет.

PS fpc 2.0.0 (с 2.0.3 появляется обилие других глюков), Laz 0.9.12 (у меня почему-то 0.9.13beta светится)

PSS Прикрепляю скриншот CallStack-а, но там название совсем другие (процедур и переменных) но смысл тот-же. SetAtomTokenArray = AddItem, первый аргумент = num, второй = i и добовлялись элементы с 500 т.е. на 503 он спаткнулся.
Может быть пригодится...
SovNarKom
постоялец
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:

Сообщение SovNarKom »

Менеджер памяти общий?
Saemon Zixel
новенький
Сообщения: 78
Зарегистрирован: 20.09.2005 18:19:54
Откуда: Sochi

Сообщение Saemon Zixel »

Нет.

После полной чистки системы и перехода на 2.0.2, вроде заработало нормально...
Но начала выскакивать ошибка переполнения стека вызовов, когда одна функция рекурсивна выводила данные. Если отключить контроль на переполнение то всё работает нормально, хотя в доке указана что стек в линуксе неограничен (а памяти у меня много). Предпологаю ошибка компилятора.

ЗЫ Всем спосибо за внимание. Пока-что полёт нормальный...
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

а зачем myarrCount? вроде есть High()
>>Менеджер памяти общий?
в приведеном примере он ненужен
Saemon Zixel
новенький
Сообщения: 78
Зарегистрирован: 20.09.2005 18:19:54
Откуда: Sochi

Сообщение Saemon Zixel »

myarrCount - экспортируется, чтоб программа знала о количестве элементов в массиве, т.к. прямого доступа к массиву у неё нет.
Saemon Zixel
новенький
Сообщения: 78
Зарегистрирован: 20.09.2005 18:19:54
Откуда: Sochi

Сообщение Saemon Zixel »

Тут недавно всплыла тупиковая ситуёвина. Почемуто неполучается динамически увеличивать динамический массив.

Код: Выделить всё

program test
type
 PChain = ^TChain;
 TChain = record
    id: integer;
    next: PChain;
  end;

var
  Chain: array of PChain;
begin
  SetLength(Chain, 1);
  Chain[0]:=GetMem(SizeOf(TChain));
  Chain[0]^.next:=nil;
//--------либо-------
  SetLength(Chain[0]^.next,1);
end.


Вылетает ошибка SYSTEM_DECLOCKED. Причём в стеке вызовов fpc_dynarray_clear до неё т.е.2 .

PS fpc2.0.2
cro096
незнакомец
Сообщения: 5
Зарегистрирован: 31.12.2005 11:56:46

Сообщение cro096 »

begin
SetLength(Chain, 1); // выделил память на массив из 1 указателя.
Chain[0]:=GetMem(SizeOf(TChain)); // выделил память под структуру
Chain[0]^.next:=nil; // занулил некс.
//--------либо-------
SetLength(Chain[0]^.next,1); { попытка задать длину массива, а вместо массива передал в функцию указатель на левую структуру.
Я че-то не понимаю?}
end.




var
Chain: array of PChain;
N : integer;
begin
SetLength(Chain, 1);
Chain[0]:=GetMem(SizeOf(TChain));
N := Length(Chain);
SetLength(Chain, N+1);
Chain[N]:=GetMem(SizeOf(TChain));
Chain[N-1]^.Next := Chain[N];
end.
SergKam
постоялец
Сообщения: 251
Зарегистрирован: 16.11.2005 20:31:11
Откуда: Украина,Харьков

Сообщение SergKam »

Размер стека компилятором ограничен. Размер его выставляется в параметрах компилятора.( кстати в delphi тоже есть stack size)
Saemon Zixel
новенький
Сообщения: 78
Зарегистрирован: 20.09.2005 18:19:54
Откуда: Sochi

Сообщение Saemon Zixel »

Хмм, а у меня мануала по fpc чётко говорит что у меня стек на всю оперативу растягивается т.е. в линуксе (да и в венде тоже). может не та мануала?
Аватара пользователя
pda
постоялец
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Сообщение pda »

В форточках по умолчанию, мегабайт максимум.
Rain
новенький
Сообщения: 21
Зарегистрирован: 19.10.2006 03:12:00

Сообщение Rain »

А у меня такая задача.
Необходимо выделять память под PChar динамически.

var
s: string;
ch_out : PChar;
number : byte;

begin
for number := 1 to length(s) do
begin
ch_out := GetMem(SizeOf(Char)*number);
ch_out[number] := string[number];
end;
end;

В ch_out видим мусор. :(
LAutour
новенький
Сообщения: 34
Зарегистрирован: 13.06.2006 10:30:34
Контактная информация:

Сообщение LAutour »

Rain
Так нельзя. GetMem выделяет новую память, а в результате ch_out каждый раз ссылается на новую область памяти с тем мусором что там был. Плюс ранее выделенная память в программе не освобождается (должен быть FreeMem). Размер выделенной памяти надо изменять с помощью ReallocMem;
Ответить