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

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

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

Сообщение IUnknown » 13.03.2006 14:12:55

Имею ввиду calloc. Что следут сделать чтобы создать аналог этой функции во FP? И как потом освободить выделенную память?
IUnknown
новенький
 
Сообщения: 73
Зарегистрирован: 10.03.2006 14:25:02
Откуда: Донецк

Сообщение Иван Шихалев » 13.03.2006 14:21:30

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

А что она делает?
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Сообщение IUnknown » 13.03.2006 14:29:29

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

void *calloc(size_t num,size_t size)

num - кол-во элементов
size - размер в байтах каждого элемента
IUnknown
новенький
 
Сообщения: 73
Зарегистрирован: 10.03.2006 14:25:02
Откуда: Донецк

Сообщение Иван Шихалев » 13.03.2006 14:37:30

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

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

Сообщение IUnknown » 13.03.2006 14:51:25

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

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

Поправьте меня если что, я со знаниями C++ пытаюсь с недавнего времени овладеть фрипаскалем :)
IUnknown
новенький
 
Сообщения: 73
Зарегистрирован: 10.03.2006 14:25:02
Откуда: Донецк

Сообщение SovNarKom » 13.03.2006 18:14:06

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

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


<span style='color:red'>Вот ниже пример, я забыл залогинится, пардон.</span>
и ещё я наврал
FillChar(byteptr,100,0); ---> FillChar(byteptr^,100,0);
FillChar(@byteArr[0],100,0); ---> FillChar(byteArr[0],100,0);
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение IUnknown » 13.03.2006 19:17:50

Похоже работает данная методика. По крайней мере в Delphi заработало. Правда пришлось еще SetLength вызывать :o
Надеюсь и в FP заработает.
Всем спасибо!
IUnknown
новенький
 
Сообщения: 73
Зарегистрирован: 10.03.2006 14:25:02
Откуда: Донецк

Сообщение Guest » 13.03.2006 20:25:48

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;

Guest
 

Сообщение IUnknown » 13.03.2006 20:59:24

Не, я вообще говорю, что алгоритм работает :) А использую именно динамические массивы. Только вот... как теперь вернуть из функции указатель на выделенную память? Можно на примере вышеприведенного кода, с SetLength который
IUnknown
новенький
 
Сообщения: 73
Зарегистрирован: 10.03.2006 14:25:02
Откуда: Донецк

Сообщение SovNarKom » 13.03.2006 22:09:45

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

Но вообще в большинстве случаев, лучше всётаки GetMem использовать и ReAllocMem, лично я динамические массивы использую только для набора классов, например, или строк.
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение STAKANOV » 14.03.2006 00:13:04

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

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

Сообщение SergKam » 14.03.2006 02:50:39

насчет освобождения памяти.
у меня такой случай был
so (DLL в линуксе) написана на си.
она возвращала указатель на выделеную ейю нутри себя память,
которую я должен был в программе освобождать.
так вот при стандартном паскалевском FreeMem постоянно выленала ошибка,
решили это только использованием Libc
Libc.Free(ptr);
SergKam
постоялец
 
Сообщения: 251
Зарегистрирован: 16.11.2005 21:31:11
Откуда: Украина,Харьков

Сообщение SovNarKom » 14.03.2006 03:22:03

SergKam
Да, понятное дело, а всё из-за менеджера памяти стандартного.
В FAQ написано что к чему. Зато по идее быстрее работает.
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение IUnknown » 14.03.2006 14:12:05

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

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

Хотелось бы сделать функцию которую можно примерно также использовать в паскале, если это возможно
IUnknown
новенький
 
Сообщения: 73
Зарегистрирован: 10.03.2006 14:25:02
Откуда: Донецк

Сообщение Nikolay » 14.03.2006 15:26:39

только к динамическим массивам не стоит применять 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 ;-)
Nikolay
 

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5

Рейтинг@Mail.ru