Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2011-03

GetMem(SomePointer, 0) nil

17 messages · 10 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Paul Ishenin

Hello, FPC developers' list.

I noticed today that if I want to allocate 0 bytes I get not a nil but a valid pointer. Why?

This is incompatible with delphi. And I suppose cause crashes and memory leaks not only in my delphi code which I'm porting to FPC/Lazarus.

Best regards, Paul Ishenin.

Reply by email

Michael Van Canneyt
to Paul Ishenin
Paul Ishenin wrote 7 lines
Hello, FPC developers' list. I noticed today that if I want to allocate 0 bytes I get not a nil but a valid pointer. Why? This is incompatible with delphi. And I suppose cause crashes and memory leaks not only in my delphi code which I'm porting to FPC/Lazarus.

Well, in all these years, you're the first to notice, so I'm not inclined to think it is a big problem.

Does it say in the Delphi docs that Nil is returned if Size=0 ?

Michael.

Reply by email

Jonas Maebe
to Paul Ishenin: Hello, FPC developers' list. I noticed today that if I want to allocate 0 bytes I get not…
Paul Ishenin wrote
I noticed today that if I want to allocate 0 bytes I get not a nil but a valid pointer. Why?

The current code that causes this comes from this (cvs) revision:

revision 1.16
date: 1999-09-17 19:14:12 +0200; author: peter; state: Exp; lines: +284 -966;
+ new heap manager supporting delphi freemem(pointer)

I guess the reason was to be able to
a) give a run time error if someone tries to do freemem(nil) b) nevertheless allow freeing all pointers that have been allocated using getmem() (even if the size was 0 bytes), for backwards compatibility with FPC code from before that revision (FPC also returned a non-nil pointer in that case)

This is incompatible with delphi.

If it is changed, it will also require changes in cmem (and probably also in heaptrc), because at least on Mac OS X libc also returns a valid pointer for malloc(0).

And I suppose cause crashes and memory leaks not only in my delphi code which I'm porting to FPC/Lazarus.

That sounds very much like badly written code.

Jonas

Reply by email

Sergei Gorelkin
to Jonas Maebe: The current code that causes this comes from this (cvs) revision: revision 1.16 date:…

Jonas Maebe пишет:

Show quoted text 15 lines
On 01 Mar 2011, at 07:32, Paul Ishenin wrote: > I noticed today that if I want to allocate 0 bytes I get not a nil but > a valid pointer. Why? The current code that causes this comes from this (cvs) revision: revision 1.16 date: 1999-09-17 19:14:12 +0200; author: peter; state: Exp; lines: +284 -966; + new heap manager supporting delphi freemem(pointer) I guess the reason was to be able to a) give a run time error if someone tries to do freemem(nil)

Delphi allows freemem(nil) without error, consistent with TObject.Free

Show quoted text 6 lines
b) nevertheless allow freeing all pointers that have been allocated using getmem() (even if the size was 0 bytes), for backwards compatibility with FPC code from before that revision (FPC also returned a non-nil pointer in that case) > This is incompatible with delphi.

I remember a discussion some time ago, the conclusion was it's compatible with TP rather than with Delphi.

Show quoted text 5 lines
If it is changed, it will also require changes in cmem (and probably also in heaptrc), because at least on Mac OS X libc also returns a valid pointer for malloc(0).

Not necessary, if we have only one GetMem function (currently we have several - getmem, fpc_getmem, getmemory and maybe something else, each calling MemoryManager independently) and write it like this:

if size=0 then
   result := nil
else
   result := MemoryManager.GetMem(size);
Show quoted text 5 lines
> And I suppose cause crashes and memory leaks not only in my delphi > code which I'm porting to FPC/Lazarus. That sounds very much like badly written code.

Fully agree.

Sergei

Reply by email

Marc Weustink
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 6 lines
Paul Ishenin schrieb: > I noticed today that if I want to allocate 0 bytes I get not a nil but > a valid pointer. Why? This will allow for a following Realloc.

Since the resulting pointer of a realloc isn't guarantied the same as the source pointer, I don't see a problem in reallocing nil.

Marc

Reply by email

Jonas Maebe
to Sergei Gorelkin: Jonas Maebe пишет: Delphi allows freemem(nil) without error, consistent with…
Sergei Gorelkin wrote
Jonas Maebe пишет: > a) give a run time error if someone tries to do freemem(nil) Delphi allows freemem(nil) without error, consistent with TObject.Free

I don't think TObject.Free and freemem are really comparable. TObject.Free is much more high level.

I remember a discussion some time ago, the conclusion was it's compatible with TP rather than with Delphi.

TP also returns nil for getmem(0) (and allows freemem(nil,0) -- TP doesn't have a freemem() function without a separate "size" parameter).

I guess it's one of the ways in which the FPC version was intended to be cleaner than the TP and Delphi versions of the same functions (and since they're RTL functions, they cannot simply be changed based on the compilation mode of the current unit). Since it's also consistent with how other memory allocators work (e.g., the libc ones), I don't think that was a bad decision.

> If it is changed, it will also require changes in cmem (and probably also in heaptrc), because at least on Mac OS X libc also returns a valid pointer for malloc(0). Not necessary, if we have only one GetMem function

It's true, that way it could also be changed.

Jonas

Reply by email

Vinzent Höfler
Micha Nelissen wrote 8 lines
Paul Ishenin wrote: > 01.03.2011 19:29, Jonas Maebe wrote: >> That sounds very much like badly written code. > For simplicity we had the next code: > GetMem(SomeArray, Count * SizeOf(ArrayCell)) > if SomeArray nil then DoSomeLogic; DoSomeLogic ... with a Count = 0, right? or was Sizeof(...) = 0? :-)

What I wonder is, if GetMem returns a non-NIL, valid pointer for a request of zero bytes of memory, where does this pointer actually point to? ;)

Vinzent.

Reply by email

Jonas Maebe
to Vinzent Höfler
Vinzent Höfler wrote
What I wonder is, if GetMem returns a non-NIL, valid pointer for a request of zero bytes of memory, where does this pointer actually point to? ;)

To a small, non-zero sized memory block.

Jonas

Reply by email

Alexander Klenin
to Hans-Peter Diettrich: This will allow for a following Realloc. Even in Delphi the behaviour may be subject to…
Hans-Peter Diettrich wrote 8 lines
Paul Ishenin schrieb: > I noticed today that if I want to allocate 0 bytes I get not a nil but a > valid pointer. Why? This will allow for a following Realloc. Even in Delphi the behaviour may be subject to the installed memory manager.

Maybe {$mode delphi} should by default install dephi-compatible memory manager?

Alexander S. Klenin

Reply by email

Paul Ishenin
to Alexander Klenin
Alexander Klenin wrote
Maybe {$mode delphi} should by default install dephi-compatible memory manager?

No. Different units cannot install different memory managers. This will be even more dangerous than to be just incompatible with delphi.

Best regards,
Paul Ishenin

Reply by email

Alexander Klenin
to Paul Ishenin
Paul Ishenin wrote 7 lines
02.03.2011 7:23, Alexander Klenin wrote: > > Maybe {$mode delphi} should by default install dephi-compatible memory > manager? No. Different units cannot install different memory managers. This will be even more dangerous than to be just incompatible with delphi.

Indeed. I was not thinking. But surely you can install such a manager for your project?

Alexander S. Klenin

Reply by email

Paul Ishenin
to Jonas Maebe: To a small, non-zero sized memory block. Jonas
Jonas Maebe wrote
To a small, non-zero sized memory block.

Memory allocation is time cost. Either user code should compare that for the zero bytes it should not call a GetMem or GetMem can compare this for user. Since GetMem already has a condition which compares for 0 - it is be the best place for doing this.

Therefore FPC GetMem is not only incompatible with delphi GetMem but also can slowdown an application if it relies on GetMem logic and does not have a special checks for Count = 0 case.

Best regards,
Paul Ishenin

Reply by email