Recent

Author Topic: System.AllocMem error make no sense  (Read 3372 times)

jamesdkfl

  • Newbie
  • Posts: 3
System.AllocMem error make no sense
« on: May 05, 2015, 09:17:00 pm »
SO following code: ===================
{$mode objfpc} {$H+}
procedure ExtractFromText(var FSrchRec: Pointer);
var
  pAddr: ^TSearchRec;
  msSize :SizeUint;
  Buffer: AnsiString;
begin
  pAddr := FSrchRec;
  msSize := pAddr^.Size;   //now 77038 from 1st entry
 try
  Buffer := System.AllocMem(msSize + 1);
=======================
compiler error
  Error: Incompatible types: got "Pointer" expected "AnsiString"

Say What???
^^^^^^^^^^^^^^^^^^^^^^^^^
according to DOCS:
http://www.freepascal.org/docs-html/rtl/system/allocmem.html  ^^^^^^^^^^^^

AllocMem
Allocate and clear memory.
Declaration
Source position: heaph.inc line 93
function AllocMem( Size: PtrUInt ):pointer;
Description
AllocMem calls getmem GetMem, and clears the allocated memory, i.e. the allocated memory is filled with Size zero bytes.

AllocMem returns a Pointer and the compiler should coerce the address returned into an AnsiString address.
FYI, if I use a 'PChar', no error msg!

My goal is to allocate enough memory to hold an entire HTML file + trailing null.
I want the memory initialized to null for debugging.


Syndrome

  • New Member
  • *
  • Posts: 35
Re: System.AllocMem error make no sense
« Reply #1 on: May 05, 2015, 09:57:59 pm »
Code: [Select]
var
  Buffer:string;
  YourPointerToData:Pointer;

...

  SetLength(Buffer, msSize+1); // Allocate memory
  FillChar(Buffer[1], Length(Buffer), 0); // Zero memory
  Move(YourPointerToData^, Buffer[1], msSize); // Move memory

jamesdkfl

  • Newbie
  • Posts: 3
Re: System.AllocMem error make no sense
« Reply #2 on: May 05, 2015, 11:59:51 pm »
That works, thanks Syndrome. 

Although the documentation doesn't mention that it WILL Allocate if needed. 

Still doesn't explain the reason System.AllocMem thought an AnsiString was a Pointer (and couldn't coerce Pointer into Address of AnsiString name!

howardpc

  • Hero Member
  • *****
  • Posts: 3681
Re: System.AllocMem error make no sense
« Reply #3 on: May 06, 2015, 01:01:59 am »
AnsiString is a compiler-managed, reference-counted type of dynamic length. Memory for an ansistring is allocated by the compiler and initialized for use when the compiler encounters an ansistring assignment. Internally the string variable is a pointer to this compiler-managed memory structure on the heap, which is disposed of automatically as soon as the variable goes out of scope.

Whereas a PChar is a slightly enhanced Pascal imitation of a pseudo-C string-array structure which has no built-in length information and relies on a trailing #0 byte to mark its end. A Pascal ansistring can have #0 characters within it without that affecting its perceived length.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8319
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: System.AllocMem error make no sense
« Reply #4 on: May 06, 2015, 01:20:31 am »
Although the documentation doesn't mention that it WILL Allocate if needed. 
I think it's mentioned clearly:
"the actual content of the string is stored on the heap, as much memory as needed to store the string content is allocated"
...
"When an ansistring is declared, the Free Pascal compiler initially allocates just memory for a pointer, not more. This pointer is guaranteed to be Nil, meaning that the string is initially empty."
...
"Memory for the string content will be allocated only when the string is assigned a value. If the string goes out of scope, then its reference count is automatically decreased by 1. If the reference count reaches zero, the memory reserved for the string is released."

Note that this will of course happens only when you manipulate AnsiString as AnsiString, not a pointer to array of byte/char. i.e.: use assignment and concatenation instead of FillChar/FillByte/Move.
Still doesn't explain the reason System.AllocMem thought an AnsiString was a Pointer (and couldn't coerce Pointer into Address of AnsiString name!
Ever heard of that Pascal's most important property is its type safety? ;)
AnsiString is INTERNALLY a pointer, but when one uses AnsiString, treat it as AnsiString, not pointer (and that's where the compiler complains). AnsiString has its own way to allocate storage (SetLength), away from manual (de)allocation.

parcel

  • Full Member
  • ***
  • Posts: 135
Re: System.AllocMem error make no sense
« Reply #5 on: May 06, 2015, 01:47:35 am »

 

TinyPortal © 2005-2018