Deutsch   English   Français   Italiano  
<vmdpi1$32g7$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: David Brown <david.brown@hesbynett.no>
Newsgroups: comp.arch
Subject: Re: Segments
Date: Fri, 17 Jan 2025 15:30:24 +0100
Organization: A noiseless patient Spider
Lines: 162
Message-ID: <vmdpi1$32g7$1@dont-email.me>
References: <vdlgl9$3kq50$2@dont-email.me> <bdZeP.23664$Hfb1.16566@fx46.iad>
 <vlj1pg$25p0e$1@dont-email.me> <87cygo97dl.fsf@nosuchdomain.example.com>
 <vm7mvi$2rr87$1@dont-email.me> <20250115140026.00003f4f@yahoo.com>
 <vm8t42$3221i$1@dont-email.me> <20250115222824.000034d6@yahoo.com>
 <vm97j3$342b3$1@dont-email.me> <vmar0d$3g078$1@dont-email.me>
 <20250116143532.00002117@yahoo.com> <vmavsb$3gpni$1@dont-email.me>
 <vmbd4n$3v6su$3@paganini.bofh.team> <vmbsvr$3lpar$1@dont-email.me>
 <vmcets$5vp2$1@paganini.bofh.team>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Fri, 17 Jan 2025 15:30:26 +0100 (CET)
Injection-Info: dont-email.me; posting-host="eac6ea3806850550cb7a14bb1d188128";
	logging-data="100871"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1//a43u5VotGbDxKdxSL3PTeYULFLT0ySw="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101
 Thunderbird/102.11.0
Cancel-Lock: sha1:A0QO4Yeu/pD16mOsrdOBmY6J6BY=
In-Reply-To: <vmcets$5vp2$1@paganini.bofh.team>
Content-Language: en-GB
Bytes: 8978

On 17/01/2025 03:22, Waldek Hebisch wrote:
> David Brown <david.brown@hesbynett.no> wrote:
>> On 16/01/2025 17:46, Waldek Hebisch wrote:
>>> David Brown <david.brown@hesbynett.no> wrote:
>>>> On 16/01/2025 13:35, Michael S wrote:
>>>>> On Thu, 16 Jan 2025 12:36:45 +0100
>>>>> David Brown <david.brown@hesbynett.no> wrote:
>>>>>
>>>>>> On 15/01/2025 21:59, Thomas Koenig wrote:
>>>>>>> Michael S <already5chosen@yahoo.com> schrieb:
>>>>>>>> On Wed, 15 Jan 2025 18:00:34 -0000 (UTC)
>>>>>>>> Thomas Koenig <tkoenig@netcologne.de> wrote:
>>>>>>>>     
>>>
>>>>> As you can guess, in kernel drivers VLA are unwelcome.
>>>>
>>>> I can imagine that they are - but I really don't understand why.  I've
>>>> never understood why people think there is something "dangerous" about
>>>> VLAs, or why they think using heap allocations is somehow "safer".
>>>
>>> VLA normally allocate on the stack.  Which at first glance look
>>> great.  But once one realize how small are stacks in modern
>>> systems (compared to whole memory), this no longer looks good.
>>> Basically, to use VLA one needs rather small bound on maximal
>>> size of array.
>>
>> Sure.
>>
>>> Given such bound always allocating maximal
>>> size is simpler.  Without _small_ bound on size heap is
>>> safer, as it is desined to handle also big allocations.
>>
>> You don't allocate anything in a VLA without knowing the bounds and
>> being sure it is appropriate to put on the stack.  You don't allocate
>> anything on the heap without knowing the bounds and being sure it is
>> appropriate.  There's no fundamental difference - it's just the cut-off
>> point that is different.
> 
> Well, AFAICS VLA-s may get allocated on function entry.  

It could be allocated as soon as the size is known, yes.

> In such
> case caller have to check for allocation size, which spreads
> allocation related code between caller and called function.

It is not about allocation sizes - it's about knowing the data you are 
dealing with, and sanitising unknown data.

In the very rough example I gave of string formatting or manipulation, 
you might be getting the strings in from outside - command line 
parameters, database entries, wildcard directory searches, etc.  You 
sanity check the data when it comes in - regardless of whether or not 
you plan to allocate memory (stack or heap) for copying them.  Now you 
know that the sizes are reasonable, you can allocate VLAs (or use 
alloca, or use malloc) without extra worries.

I am not suggesting you should have some kind of rule to check sizes 
just before every VLA declaration - I am suggesting that when you know 
the size is reasonable and safe, then using a VLA is reasonable and safe.


> In case of 'malloc' one can simply check return value.  

Drivel.

That's a myth that originated in the days of K&R C.

It is certainly true that if malloc returns 0, your allocation has 
failed.  There are a few - but only a very few - circumstances where 
that is something that can realistically happen in code that is doing 
its job properly.  Typically that would be in resource-constrainted 
systems where you might have some unusual circumstances causing overload.

But generally (and this means there will be exceptions), checking for 
null returns from malloc is :

a) Never properly tested, and often results in leaked resources or other 
problems;

b) Totally unrealistic in any real-world use of the code;

c) Treated as though it is a divine duty that must always be done 
ritually and religiously;

d) Treated as though it magically makes the code safe, correct and reliable.

Hopefully you can see that these points are self-contradictory.


If you try to call malloc with a size that is unreasonable for the 
circumstances, all kinds of bad things can happen /despite/ a non-null 
return value.  What goes wrong can depend on many factors, including the 
OS, the malloc library, the size, the system setup, and what you do with 
the returned pointer.  Simply /trying/ to run malloc with a bad size 
may, on some systems, lead to the OS trying to free up as much memory as 
it can in order to accommodate your request - whether malloc ends up 
returning null or not.  Or maybe the request is done in with lazy 
allocations - you asked for 100 TB of memory and you got a pointer back, 
and things will only go wrong when you start using the virtual space.

Remember, from the point of view of people using the computer, having 
the OS push lots of stuff out of memory is tantamount to a broken 
system.  A program that has runaway memory usage causes great 
frustration, and often leads to users doing a hard reset.  And all the 
time, the malloc() calls have returned a non-null value.


So what does all that mean?  It means you do /not/ blindly call 
malloc(), check for a null result, and think that's all good.  It means 
you be sure you know what sizes you are asking for /before/ you call 
malloc - probably long before you get to the bit of code that actually 
calls malloc().  It means you look /before/ you leap - you don't "just 
go for it" and hope that you can figure out what went wrong from the 
debris left at the crash site.

And if you are in doubt - maybe you are pushing the target system to the 
limits, or have a program that demands more memory than many systems 
might have - you check in advance to see if the memory will be easily 
available.  Such checks will be OS specific, of course.

(I'm sure some people will now be thinking "you should have used 
ulimit", or "don't enable swap", or "that's the fault of over-commit". 
That would all be missing the point.  You can of course use such tools 
as a way of making sure your sizes are reasonable - it's up to the 
developer to decide how to handle such checks and controls.  But 
checking the return of malloc is so far from being sufficient that it is 
basically useless in most circumstances.)


It is /exactly/ the same for VLAs (or alloca).


The limits for what sizes are "reasonable" will, of course, be smaller 
for stack allocations than for heap allocations.  But that's all target 
dependent anyway - for the systems I typically work with, the limit for 
"reasonable" heap allocations is orders of magnitude smaller than 
"reasonable" stack allocations on desktops.

> In fact,
> in many programs simple wrapper that exits in case of allocation
> failure is enough (if application can not do its work without
> memory and there is no memory, then there is no point in continuing
> execution).

Have you ever seen that happening in real life?  Have you ever even 
known such code to be properly tested?

Don't get me wrong - a wrapper like this can be a good idea.  But it's 
like an electrical fuse - it's a last resort, and only triggers if 
something has gone badly wrong.  When you see a great music system with 
a 10 kW amplifier, you check if your house electrical system can handle 
that /before/ you buy it.  You don't buy it, plug it in and rely on the 
fusebox to keep your house from burning down - even though you want the 
fuse there as a failsafe.  For the most part, if malloc ever returns 0, 
the problem lies before malloc is called.


(Sorry for the rant - "my code is safe because I check the result of 
malloc" is one of these misconceptions that really annoy me.)