Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

delphi invalid pointer operation

Here I have a few lines of delphi code running in delphi 7:

    var
      ptr:Pointer ;
    begin
      ptr:=AllocMem(40);
      ptr:=Pchar('OneNationUnderGod');
      if ptr<>nil then
        FreeMem(ptr);
    end;

Upon running this code snippet, FreeMem(ptr)will raise an error:'invalid pointer operation'. If I delete the sentence:

     ptr:=Pchar('OneNationUnderGod');

then no error will occur. Now I have two questions,

1.Why is this happening? 2. If I have to use the Pchar sentence, how should I free the memory allocated earlier?

Much appreciation for your help!

like image 517
world peace Avatar asked Feb 10 '26 23:02

world peace


2 Answers

The problem is that you are modifying the address held in the variable ptr.

You call AllocMem to allocate a buffer, which you refer to using ptr. That much is fine. But you must never change the value of ptr, the address of the buffer. And you do change it.

You wrote:

ptr:=AllocMem(40);
ptr:=Pchar('OneNationUnderGod');

The second line is the problem. You have modified ptr and now ptr refers to something else (a string literal held in read-only memory as it happens). You have now lost track of the buffer allocated by your call to AllocMem. You asked AllocMem for a new block of memory and then immediately discarded that block of memory.

What you presumably mean to do is to copy the string. Perhaps like this:

ptr := AllocMem(40);
StrCopy(ptr, 'OneNationUnderGod');

Now we are fine to call FreeMem, because ptr still contains the address that the call to AllocMem provided.

ptr := AllocMem(40);
try
  StrCpy(ptr, 'OneNationUnderGod');
  // do stuff with ptr
finally
  FreeMem(ptr);
end;

Clearly in real code you would find a better and more robust way to specify buffer lengths than a hard-coded value.


In your code, assuming the above fix is applied, the test for ptr being nil is needless. AllocMem never returns nil. Failure of AllocMem results in an exception being raised.


Having said all that, it's not usual to operate on string buffers in this way. It is normal to use Delphi strings. If you need a PChar, for instance to use with interop, make one with PChar(str) where str is of type string.

You say that you must use dynamically allocated PChar buffers. Perhaps that is so, but I very much doubt it.

like image 62
David Heffernan Avatar answered Feb 12 '26 15:02

David Heffernan


It crashes because you are freeing static memory that was not dynamically allocated. There is no need to free memory used by literals at all. Only free memory that is dynamically allocated.

like image 36
Remy Lebeau Avatar answered Feb 12 '26 15:02

Remy Lebeau



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!