Аналог сишной функции

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

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

IUnknown
новенький
Сообщения: 73
Зарегистрирован: 10.03.2006 13:25:02
Откуда: Донецк

Сообщение IUnknown »

Имею ввиду calloc. Что следут сделать чтобы создать аналог этой функции во FP? И как потом освободить выделенную память?
Аватара пользователя
Иван Шихалев
энтузиаст
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург
Контактная информация:

Сообщение Иван Шихалев »

Что следут сделать чтобы создать аналог этой функции во FP?

А что она делает?
IUnknown
новенький
Сообщения: 73
Зарегистрирован: 10.03.2006 13:25:02
Откуда: Донецк

Сообщение IUnknown »

Выделяет в памяти массив и устанавливает его элементы в 0.

void *calloc(size_t num,size_t size)

num - кол-во элементов
size - размер в байтах каждого элемента
Аватара пользователя
Иван Шихалев
энтузиаст
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург
Контактная информация:

Сообщение Иван Шихалев »

Насколько я помню, при использовании getMem() память инициализируется нулями. Нужно уточнить в документации. Кроме того, есть процедуры для быстрой заливки области памяти заданным значением: FillByte(), FillChar(), FillWord(), FillDWord().

Ну и само-собой размер будет num*size.
IUnknown
новенький
Сообщения: 73
Зарегистрирован: 10.03.2006 13:25:02
Откуда: Донецк

Сообщение IUnknown »

По-моему документация умалчивает про то с памятью становится после GetMem, а компилятора сейчас под рукой нету :(

Вообще если я правльно понял алгоритм дожен быть примерно такой :
1. Выделить память с помощью GetMem
2. Обнулить с помощью FillChar например

Поправьте меня если что, я со знаниями C++ пытаюсь с недавнего времени овладеть фрипаскалем :)
SovNarKom
постоялец
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:

Сообщение SovNarKom »

Вот например в ReAllocMem написано, что если память была увеличена, то нулями это пространство НЕ заполняется.

Понял ты правильно.


<span style='color:red'>Вот ниже пример, я забыл залогинится, пардон.</span>
и ещё я наврал
FillChar(byteptr,100,0); ---> FillChar(byteptr^,100,0);
FillChar(@byteArr[0],100,0); ---> FillChar(byteArr[0],100,0);
IUnknown
новенький
Сообщения: 73
Зарегистрирован: 10.03.2006 13:25:02
Откуда: Донецк

Сообщение IUnknown »

Похоже работает данная методика. По крайней мере в Delphi заработало. Правда пришлось еще SetLength вызывать :o
Надеюсь и в FP заработает.
Всем спасибо!
Guest

Сообщение Guest »

IUnknown
СТОООП, Какой SetLength??? Это же для динамических массивов, не надо тебе его!
Как с ним вообще это работать может?

Вот пример

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


type
   pByte = ^Byte;

var
   byteptr: pByte;

begin
   byteptr:=GetMem(100);
   FillChar(byteptr,100,0);
   byteptr[25]:=224;
   FreeMem(byteptr);
end;



С SetLength это будет выглядеть так

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

type
  TByteArr = Array of Byte;

var
  byteArr: TByteArr;

begin
  SetLength(byteArr,100);
  FillChar(@byteArr[0],100,0);
  byteArr[25]:=224;
  SetLength(byteArr,0);
end;

IUnknown
новенький
Сообщения: 73
Зарегистрирован: 10.03.2006 13:25:02
Откуда: Донецк

Сообщение IUnknown »

Не, я вообще говорю, что алгоритм работает :) А использую именно динамические массивы. Только вот... как теперь вернуть из функции указатель на выделенную память? Можно на примере вышеприведенного кода, с SetLength который
SovNarKom
постоялец
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:

Сообщение SovNarKom »

@byteArr[0] - вот указатель

Но вообще в большинстве случаев, лучше всётаки GetMem использовать и ReAllocMem, лично я динамические массивы использую только для набора классов, например, или строк.
Аватара пользователя
STAKANOV
энтузиаст
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение STAKANOV »

А использую именно динамические массивы.

только к динамическим массивам не стоит применять FillChar и тп., т.к. разные части массива могут находится в разных местах.
SergKam
постоялец
Сообщения: 251
Зарегистрирован: 16.11.2005 20:31:11
Откуда: Украина,Харьков

Сообщение SergKam »

насчет освобождения памяти.
у меня такой случай был
so (DLL в линуксе) написана на си.
она возвращала указатель на выделеную ейю нутри себя память,
которую я должен был в программе освобождать.
так вот при стандартном паскалевском FreeMem постоянно выленала ошибка,
решили это только использованием Libc
Libc.Free(ptr);
SovNarKom
постоялец
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:

Сообщение SovNarKom »

SergKam
Да, понятное дело, а всё из-за менеджера памяти стандартного.
В FAQ написано что к чему. Зато по идее быстрее работает.
IUnknown
новенький
Сообщения: 73
Зарегистрирован: 10.03.2006 13:25:02
Откуда: Донецк

Сообщение IUnknown »

Что-то я совсем запутался. Какой-то дремучий лес этот паскаль :) FillChar опасно использовать... В С я могу так сделать

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

char* arr;

arr = (char *)calloc( 10, sizeof( char ) );

Хотелось бы сделать функцию которую можно примерно также использовать в паскале, если это возможно
Nikolay

Сообщение Nikolay »

только к динамическим массивам не стоит применять FillChar и тп., т.к. разные части массива могут находится в разных местах.


Абалдеть :-) Такое впечатление, что Вы чего-то путаете. Наверное, страничное распределение памяти с чем-то еще :-)
Вот, если бы у Вас был массив указателей на что-то, то да - это что-то в разных частях. А динамический массив по определению выделяется одним куском на один указатель. Если Вы захотите его увеличить, то выделится новый кусок, все скопируется, и удалится старый.

char* arr;

arr = (char *)calloc( 10, sizeof( char ) );


var arr ^Char;
...
GetMem(Arr, 10*Sizeof(Char));
// FillChar ? Надо посмотреть. По моему не надо этого

отсюда function MyGetMem(Count, Size: Integer): pointer;
begin
GetMem(Result, Count, Size);
end;

А вообще, расслабьтесь и пишите на паскале - используйте AnsiString и SetLenght ;-)
Ответить