Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #95194 > unrolled thread
| Started by | "Mr. Man-wai Chang" <toylet.toylet@gmail.com> |
|---|---|
| First post | 2016-10-24 02:20 +0800 |
| Last post | 2016-11-04 02:31 +0800 |
| Articles | 20 on this page of 78 — 14 participants |
Back to article view | Back to comp.lang.c
VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-24 02:20 +0800
VC++ 2013, malloc() and free() asetofsymbols@gmail.com - 2016-10-23 11:44 -0700
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-25 12:46 +0800
Re: VC++ 2013, malloc() and free() Melzzzzz <mel@zzzzz.com> - 2016-10-25 07:15 +0200
Re: VC++ 2013, malloc() and free() supercat@casperkitty.com - 2016-10-25 07:15 -0700
Re: VC++ 2013, malloc() and free() Melzzzzz <mel@zzzzz.com> - 2016-10-25 16:18 +0200
Re: VC++ 2013, malloc() and free() supercat@casperkitty.com - 2016-10-25 07:32 -0700
Re: VC++ 2013, malloc() and free() Melzzzzz <mel@zzzzz.com> - 2016-10-25 16:55 +0200
Re: VC++ 2013, malloc() and free() jameskuyper@verizon.net - 2016-10-25 08:07 -0700
Re: VC++ 2013, malloc() and free() "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-10-24 22:30 -0700
Re: VC++ 2013, malloc() and free() Melzzzzz <mel@zzzzz.com> - 2016-10-25 07:46 +0200
Re: VC++ 2013, malloc() and free() "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-10-25 17:54 -0700
Re: VC++ 2013, malloc() and free() "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-10-25 17:55 -0700
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-25 22:32 +0800
Re: VC++ 2013, malloc() and free() Melzzzzz <mel@zzzzz.com> - 2016-10-25 16:46 +0200
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-25 23:24 +0800
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-25 23:52 +0800
Re: VC++ 2013, malloc() and free() supercat@casperkitty.com - 2016-10-25 08:01 -0700
Re: VC++ 2013, malloc() and free() Melzzzzz <mel@zzzzz.com> - 2016-10-25 17:23 +0200
Re: VC++ 2013, malloc() and free() supercat@casperkitty.com - 2016-10-25 09:09 -0700
Re: VC++ 2013, malloc() and free() Keith Thompson <kst-u@mib.org> - 2016-10-25 09:29 -0700
Re: VC++ 2013, malloc() and free() Melzzzzz <mel@zzzzz.com> - 2016-10-25 18:51 +0200
Re: VC++ 2013, malloc() and free() raltbos@xs4all.nl (Richard Bos) - 2016-10-27 19:54 +0000
Re: VC++ 2013, malloc() and free() supercat@casperkitty.com - 2016-10-27 15:06 -0700
Re: VC++ 2013, malloc() and free() Keith Thompson <kst-u@mib.org> - 2016-10-27 17:06 -0700
Re: VC++ 2013, malloc() and free() supercat@casperkitty.com - 2016-10-28 06:47 -0700
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-29 23:16 +0800
Re: VC++ 2013, malloc() and free() supercat@casperkitty.com - 2016-10-29 09:35 -0700
Re: VC++ 2013, malloc() and free() "James R. Kuyper" <jameskuyper@verizon.net> - 2016-10-29 12:51 -0400
Re: VC++ 2013, malloc() and free() supercat@casperkitty.com - 2016-10-29 14:26 -0700
Re: VC++ 2013, malloc() and free() jameskuyper@verizon.net - 2016-10-29 15:27 -0700
Re: VC++ 2013, malloc() and free() supercat@casperkitty.com - 2016-10-29 17:11 -0700
Re: VC++ 2013, malloc() and free() Geoff <geoff@invalid.invalid> - 2016-10-31 13:01 -0700
Re: VC++ 2013, malloc() and free() Jerry Stuckle <jstucklex@attglobal.net> - 2016-10-31 16:35 -0400
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-01 15:31 +0800
Re: VC++ 2013, malloc() and free() Jerry Stuckle <jstucklex@attglobal.net> - 2016-11-01 11:28 -0400
Re: VC++ 2013, malloc() and free() Geoff <geoff@invalid.invalid> - 2016-10-31 12:11 -0700
Re: VC++ 2013, malloc() and free() supercat@casperkitty.com - 2016-10-31 13:08 -0700
Re: VC++ 2013, malloc() and free() Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-23 21:35 +0100
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-25 12:49 +0800
Re: VC++ 2013, malloc() and free() Melzzzzz <mel@zzzzz.com> - 2016-10-25 07:16 +0200
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-25 22:30 +0800
Re: VC++ 2013, malloc() and free() "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-10-23 15:52 -0700
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-25 12:50 +0800
Re: VC++ 2013, malloc() and free() Melzzzzz <mel@zzzzz.com> - 2016-10-25 07:18 +0200
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-25 22:28 +0800
Re: VC++ 2013, malloc() and free() Melzzzzz <mel@zzzzz.com> - 2016-10-25 16:48 +0200
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-25 23:25 +0800
Re: VC++ 2013, malloc() and free() Melzzzzz <mel@zzzzz.com> - 2016-10-25 17:35 +0200
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-25 23:50 +0800
Re: VC++ 2013, malloc() and free() Melzzzzz <mel@zzzzz.com> - 2016-10-25 18:45 +0200
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-10-26 01:59 +0800
Re: VC++ 2013, malloc() and free() Geoff <geoff@invalid.invalid> - 2016-10-31 12:10 -0700
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-01 15:32 +0800
Re: VC++ 2013, malloc() and free() Jerry Stuckle <jstucklex@attglobal.net> - 2016-11-01 11:31 -0400
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-03 19:28 +0800
Re: VC++ 2013, malloc() and free() Jerry Stuckle <jstucklex@attglobal.net> - 2016-11-03 10:00 -0400
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-03 23:25 +0800
Re: VC++ 2013, malloc() and free() Keith Thompson <kst-u@mib.org> - 2016-11-03 09:03 -0700
[OT] "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-04 02:33 +0800
Re: [OT] Keith Thompson <kst-u@mib.org> - 2016-11-03 12:26 -0700
Re: [OT] "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-04 12:05 +0800
Re: [OT] luser droog <luser.droog@gmail.com> - 2016-11-03 21:52 -0700
Re: [OT] "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-04 21:59 +0800
Re: [OT] Keith Thompson <kst-u@mib.org> - 2016-11-04 08:45 -0700
Re: [OT] James Kuyper <jameskuyper@verizon.net> - 2016-11-04 11:49 -0400
Re: [OT] "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-05 00:33 +0800
Re: [OT] Keith Thompson <kst-u@mib.org> - 2016-11-04 09:56 -0700
Re: [OT] "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-05 01:40 +0800
Re: [OT] "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-05 01:42 +0800
Re: [OT] Keith Thompson <kst-u@mib.org> - 2016-11-04 11:52 -0700
Re: [OT] "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-05 18:13 +0800
Re: [OT] Keith Thompson <kst-u@mib.org> - 2016-11-05 13:19 -0700
Re: [OT] "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-06 16:00 +0800
Re: VC++ 2013, malloc() and free() Jerry Stuckle <jstucklex@attglobal.net> - 2016-11-03 20:16 -0400
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-05 00:34 +0800
Re: VC++ 2013, malloc() and free() supercat@casperkitty.com - 2016-11-03 08:54 -0700
Re: VC++ 2013, malloc() and free() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-04 02:31 +0800
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-10-25 09:29 -0700 |
| Message-ID | <lny41c8k9q.fsf@kst-u.example.com> |
| In reply to | #95295 |
supercat@casperkitty.com writes:
[...]
> Trying to handle allocation failures when they occur is ugly, but it's at
> least possible to write code to recover from allocation failures somewhat
> gracefully. If a call to malloc() may yield a pointer to an address that
> could cause a critical failure when code tries to use it, and if there's
> no requirement that applications be able to tell when malloc() might have
> done so, is there any way to write code that uses malloc() storage and is
> guaranteed not to invoke UB?
Undefined behavior is behavior that's not defined by the C standard.
The C standard defines the behavior of malloc(). It either successfully
allocates memory which the program can then use, or it fails and returns
a null pointer.
If a program calls malloc() and gets a non-null pointer, but the program
crashes when it tries to use the allocated memory, that's not UB on the
program's part, it's a failure in the environment.
On the other hand, a program can crash at any time for any reason, such
as a sledgehammer to the CPU, and nothing the standard says can prevent
that.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Melzzzzz <mel@zzzzz.com> |
|---|---|
| Date | 2016-10-25 18:51 +0200 |
| Message-ID | <20161025185150.068df6e6@maxa-pc.cpe.bvcom.net> |
| In reply to | #95295 |
On Tue, 25 Oct 2016 09:09:31 -0700 (PDT) supercat@casperkitty.com wrote: > On Tuesday, October 25, 2016 at 10:23:23 AM UTC-5, Melzzzzz wrote: > > Malloc is not part of the system, usually. > > If you think about overcommit it is necessary on some setups, > > especially for GarbageCollector based programs. > > I'm not clear on the advantages of overcommitting storage. I can > understand that if code allocates memory it may be advantageous for a > paging system to defer mapping it to physical page of RAM or assigning > its physical location in the paging file until code is going to use > it, but I would think it should be possible to keep track of the > quantity of outstanding requests and start refusing requests as soon > as the number of outstanding request matches the number of free > blocks remaining. > > Trying to handle allocation failures when they occur is ugly, but > it's at least possible to write code to recover from allocation > failures somewhat gracefully. If a call to malloc() may yield a > pointer to an address that could cause a critical failure when code > tries to use it, and if there's no requirement that applications be > able to tell when malloc() might have done so, is there any way to > write code that uses malloc() storage and is guaranteed not to invoke > UB? Concerning overcommit, malloc will almost never return NULL. There is of course configurable limit even for overcommit. Problem is that one can allocate more and then start to use it leading to program termination even if malloc returned some address. That's certainly trade-of. -- press any key to continue or any other to quit
[toc] | [prev] | [next] | [standalone]
| From | raltbos@xs4all.nl (Richard Bos) |
|---|---|
| Date | 2016-10-27 19:54 +0000 |
| Message-ID | <58125aaa.7762265@news.xs4all.nl> |
| In reply to | #95295 |
supercat@casperkitty.com wrote: > On Tuesday, October 25, 2016 at 10:23:23 AM UTC-5, Melzzzzz wrote: > > Malloc is not part of the system, usually. > > If you think about overcommit it is necessary on some setups, > > especially for GarbageCollector based programs. > > I'm not clear on the advantages of overcommitting storage. AFAICT the main advantage is that the system can more easily deal with lazy, unnecessarily greedy programmers, at the price of tempting even more programmers into even more laziness and unnecessary greed. > Trying to handle allocation failures when they occur is ugly, but it's at > least possible to write code to recover from allocation failures somewhat > gracefully. If a call to malloc() may yield a pointer to an address that > could cause a critical failure when code tries to use it, and if there's > no requirement that applications be able to tell when malloc() might have > done so, is there any way to write code that uses malloc() storage and is > guaranteed not to invoke UB? No. Which, IYAM, makes overcommitting systems blatantly and insultingly non-conforming. IMAO, overcommitting storage goes against the Unix philosophy of trusting the programmer to dig his own grave, but who am I? Richard
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-10-27 15:06 -0700 |
| Message-ID | <d41f6e2f-2aa4-4fb4-8adb-570e3d421455@googlegroups.com> |
| In reply to | #95351 |
On Thursday, October 27, 2016 at 2:55:05 PM UTC-5, Richard Bos wrote: > No. Which, IYAM, makes overcommitting systems blatantly and insultingly > non-conforming. The Standard is extremely wishy-washy with regard to implementation limits and the effect of exceeding them. Provided that there exists at least one program which nominally exercises the implementation limits given in the Standard without invoking UB, an implementation may invoke UB at any time with any other program if it exceeds an implementation limit. To forbid an implementation from dying if a program tries to malloc() too much storage would severely constrain the useful behaviors of C compilers on many machines (a compiler for any platform could statically allocate a pool and limit malloc to using that, but for many purposes being able to request more unless or until things die is actually more useful).
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-10-27 17:06 -0700 |
| Message-ID | <lnwpgt5obr.fsf@kst-u.example.com> |
| In reply to | #95353 |
supercat@casperkitty.com writes:
> On Thursday, October 27, 2016 at 2:55:05 PM UTC-5, Richard Bos wrote:
>> No. Which, IYAM, makes overcommitting systems blatantly and insultingly
>> non-conforming.
>
[...]
> To forbid an
> implementation from dying if a program tries to malloc() too much storage
> would severely constrain the useful behaviors of C compilers on many machines
> (a compiler for any platform could statically allocate a pool and limit
> malloc to using that, but for many purposes being able to request more
> unless or until things die is actually more useful).
Overcommitting isn't about a program dying when it tries to malloc()
too much storage. It's about a program (or some other process on
the system) dying when it (a) attempts to allocate memory by calling
malloc(), (b) gets back a non-null pointer indicating that malloc()
succeeded, *and then* (c) tries to access that memory.
Perhaps you already knew that, but it wasn't clear from what you wrote
above.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-10-28 06:47 -0700 |
| Message-ID | <8c25dcba-9296-4cdd-838e-540c4685aba1@googlegroups.com> |
| In reply to | #95354 |
On Thursday, October 27, 2016 at 7:06:45 PM UTC-5, Keith Thompson wrote: > Overcommitting isn't about a program dying when it tries to malloc() > too much storage. It's about a program (or some other process on > the system) dying when it (a) attempts to allocate memory by calling > malloc(), (b) gets back a non-null pointer indicating that malloc() > succeeded, *and then* (c) tries to access that memory. > > Perhaps you already knew that, but it wasn't clear from what you wrote > above. Most implementations of malloc() can be divided into four groups: 1. They will either return a valid pointer, or return null with no adverse side-effects. 2. They will either return a valid pointer, or terminate abnormally. 3. They will return a pointer which may turn out to be valid or which may look valid but cause the program to terminate abnormally if it's actually used. 4. They will return a pointer which may turn out to be valid or which may look valid but cause unpredictable behavior if it's actually used (typically as a consequence of heap/stack collision). It would IMHO have been helpful if there were a macro that specified how an implementation of malloc will behave. That would entitle programmers who test for that macro to safely make assumptions about how malloc() will behave. An implementation which fails, for no good reason, to offer no promises beyond #4 would of low quality but nonetheless conforming, while one which promises #1 or #2 but still behaves like #4 would be non-conforming.
[toc] | [prev] | [next] | [standalone]
| From | "Mr. Man-wai Chang" <toylet.toylet@gmail.com> |
|---|---|
| Date | 2016-10-29 23:16 +0800 |
| Message-ID | <nv2efl$99s$4@dont-email.me> |
| In reply to | #95359 |
On 28/10/2016 9:47 PM, supercat@casperkitty.com wrote: > 2. They will either return a valid pointer, or terminate abnormally. This is the worst-case scenario! Then how could I ask for memory politely without being beaten up? :)
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-10-29 09:35 -0700 |
| Message-ID | <367030c2-5377-4312-b8b8-d973ecfa379a@googlegroups.com> |
| In reply to | #95382 |
On Saturday, October 29, 2016 at 10:16:36 AM UTC-5, Mr. Man-wai Chang wrote:
> On 28/10/2016 9:47 PM, supercat wrote:
> > 2. They will either return a valid pointer, or terminate abnormally.
>
> This is the worst-case scenario! Then how could I ask for memory
> politely without being beaten up? :)
That's not the worst-case scenario. In some real-world systems, stack grows
from the top of memory and the heap grows from the bottom, and there isn't a
fixed limit for either; if the stack doesn't cross the heap high-water mark,
all will be okay, but if the stack does collide with the heap and the option
to check stack on every subroutine call isn't enbabled, a collision may have
arbitrary and unpredictable consequences (at least one such system, the 1984
Macintosh, would check 60 times/second whether the top of the heap had been
clobbered and trigger a system error if it had, but arbitrary consequences
could still occur before that was discovered).
Further, if one is writing a program which will be able to function usefully
if every malloc-family call succeeds, which will not be able to do anything
useful if any such call fails, and which only make such calls at times when
abrupt program termination would be acceptable, a guarantee that a failed
malloc will abnormally terminate the program rather than yielding null would
eliminate the need for null checks on the malloc result [personally I think
the "right" way to handle that would have been to have a standard-library
variations of malloc etc. which would be essentially equivalent to:
void *malloc_checked(size_t size) // May be mapped to 6-char name
// via macro
{
void *ret = malloc(size);
if (!ret) { fprintf(stderr, "Out of memory\n"); abort(); }
return ret;
}
but with the precise details of the failure being implementation-defined
*except* for a requirement that the function never return anything other
than a valid pointer. Letting the implementation take care of such issues
rather than simply reporting the out-of-memory condition to the application
would not only simplify end-user code, but might let implementation offer
behaviors that wouldn't be possible if memcpy simply failed (e.g. an
implementation could suspend the application and inform someone at the
console that it needed more memory to continue; the operator could then
either kill that application, kill another application to free up memory,
or wait for some other application to finish naturally and free up memory.)
Incidentally, even systems which overcommit memory could, in theory, offer
operators the same kind of choice when the system is found to be over-
committed or dangerously close to it, and that could justify implementations
where attempting to allocate an overcommitted page results in an abnormal
program termination but that does not cause any other adverse consequences.
Nothing in the Standard would prohibit *any action* from pausing while the
operator examines system state or does anything else, if the operator then
lets the program resume execution as though nothing had happened. Since
the Standard would have no authority to punish an operator who does not let
the program resume, it would be illogical for it to forbid an operator from
deciding to kill the program. It would also be illogical to forbid an
operator from indicating in advance that if a situation arose where action
would be required for an application to continue, it should be killed
instead.
What's key is the distinction between allowing a program to be terminated
in an implementation-defined manner, versus allowing unconstrained behavior.
If an attempted action may have several possible consequences but all would
meet requirements if handled the same way, there's no need for code to care
which consequence occurred. For many kinds of programs, abnormal program
termination is an acceptable behavior if the intended task cannot be
completed, and is thus hardly a "worst-case scenario".
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2016-10-29 12:51 -0400 |
| Message-ID | <bbc722bc-4a90-7f32-e0c1-a952d211ef76@verizon.net> |
| In reply to | #95382 |
On 10/29/2016 11:16 AM, Mr. Man-wai Chang wrote: > On 28/10/2016 9:47 PM, supercat@casperkitty.com wrote: >> 2. They will either return a valid pointer, or terminate abnormally. > > This is the worst-case scenario! Then how could I ask for memory > politely without being beaten up? :) A conforming implementation of malloc() must either return a pointer to a block of memory, of at least the specified size, that can actually be used, or it must return a null pointer; abnormal termination would render it non-conforming. That's one reason why it's not possible to conform to the C standard when targeting a platform configured to allow memory to be over-committed.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-10-29 14:26 -0700 |
| Message-ID | <50ba26ba-3658-4c25-8416-d50c16395fff@googlegroups.com> |
| In reply to | #95390 |
On Saturday, October 29, 2016 at 11:51:44 AM UTC-5, James R. Kuyper wrote: > A conforming implementation of malloc() must either return a pointer to > a block of memory, of at least the specified size, that can actually be > used, or it must return a null pointer; abnormal termination would > render it non-conforming. That's one reason why it's not possible to > conform to the C standard when targeting a platform configured to allow > memory to be over-committed. Provided that there exists One Program for an implementation that exercises all the implementation limits given in the Standard, and which the implementation will consistently process fully according to the Standard, the Standard deliberately declines to specify what conditions might arise that would cause a program to crash because of implementation limits, regarding such issues as a quality-of-implementation matter. I don't think anything would forbid an implementation which, when it ran out of memory, would suspend program execution and sound a klaxon until someone acquired another memory board and plugged it into an unused slot, whereupon it would resume program execution where it left off. It wouldn't matter whether the klaxon was triggered by a malloc() or by a later attempt to use the allocated storage. If conformance or lack thereof were made depend upon the behavior of a future operator who might hear the klaxon, that would imply that conformance would be dependent upon unknowable future events. Not very helpful. It would be nice if the Standard allowed implementations to promise one or two of: 1. malloc() can be expected to always return, but the return value might be null. 2. malloc() will never return null. 3. any use of a non-null pointer returned by malloc() will not impede program flow do to block overcommittal or other such causes. No implementation could promise all three, but many could promise some combination of two.
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2016-10-29 15:27 -0700 |
| Message-ID | <5b414cc6-975f-485d-896c-244987569d22@googlegroups.com> |
| In reply to | #95400 |
On Saturday, October 29, 2016 at 5:26:34 PM UTC-4, supe...@casperkitty.com wrote: > On Saturday, October 29, 2016 at 11:51:44 AM UTC-5, James R. Kuyper wrote: > > A conforming implementation of malloc() must either return a pointer to > > a block of memory, of at least the specified size, that can actually be > > used, or it must return a null pointer; abnormal termination would > > render it non-conforming. That's one reason why it's not possible to > > conform to the C standard when targeting a platform configured to allow > > memory to be over-committed. > > Provided that there exists One Program for an implementation that exercises > all the implementation limits given in the Standard, and which the > implementation will consistently process fully according to the Standard, > the Standard deliberately declines to specify what conditions might arise > that would cause a program to crash because of implementation limits, > regarding such issues as a quality-of-implementation matter. When the standard provides an explicit way for reporting the fact that a requested operation cannot be performed, a conforming implementation cannot use inability to perform that operation to justify producing any observable behavior other than using that way to report that fact. This applies to the memory allocation functions and pretty much all of the I/O functions. > I don't think anything would forbid an implementation which, when it ran > out of memory, would suspend program execution and sound a klaxon until > someone acquired another memory board and plugged it into an unused slot, > whereupon it would resume program execution where it left off. It wouldn't > matter whether the klaxon was triggered by a malloc() or by a later attempt > to use the allocated storage. If conformance or lack thereof were made > depend upon the behavior of a future operator who might hear the klaxon, > that would imply that conformance would be dependent upon unknowable > future events. ... Whether or not the operator ever adds the requested memory has no affect on conformance. Suspending operations until the memory is added is perfectly acceptable. If malloc() gave up waiting for the operator to add the memory, and either a) returned a non-null pointer which cannot, in fact, be safely used or b) abnormally terminates the program, those would render the implementation non-conforming, but returning a null pointer would be perfectly acceptable. > ... Not very helpful. The standard makes no guarantees about how long any particular operation takes, which is decidedly unhelpful if you have any finite time requirements. A conforming implementation of C can be arbitrarily unhelpful - that's a matter of QoI, outside the scope of the standard, and something for the marketplace to deal with. If an implementation wastes too much time doing stupid stuff like that, you have every right to switch to a different compiler which doesn't - but no right to complain about the first implementation being non-conforming (at least, not for that reason). However, that's not particularly relevant to the question at hand. The fact that it has a way of reporting an inability to fulfill the request means it's not conforming if it responds to that inability by any method other than returning a null pointer. However, it's fully conforming if it either returns a null pointer or waits until the memory is installed before returning a non-null pointer that can safely be used, no matter how long it takes to decide which of those two options to perform.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-10-29 17:11 -0700 |
| Message-ID | <11ca5785-1f79-47e0-8e26-ab4ac76a3d07@googlegroups.com> |
| In reply to | #95402 |
On Saturday, October 29, 2016 at 5:28:20 PM UTC-5, james wrote: > On Saturday, October 29, 2016 at 5:26:34 PM UTC-4, supercat wrote: > > Provided that there exists One Program for an implementation that exercises > > all the implementation limits given in the Standard, and which the > > implementation will consistently process fully according to the Standard, > > the Standard deliberately declines to specify what conditions might arise > > that would cause a program to crash because of implementation limits, > > regarding such issues as a quality-of-implementation matter. > > When the standard provides an explicit way for reporting the fact that a > requested operation cannot be performed, a conforming implementation cannot use > inability to perform that operation to justify producing any observable > behavior other than using that way to report that fact. This applies to the > memory allocation functions and pretty much all of the I/O functions. There are a lot of places where the most helpful thing for a standard to do is specify that quality implementations should do certain things *when practical* but acknowledge that implementations may be unable to do those things but nonetheless be useful for purposes that don't require them. A quality implementation of malloc() will return null in preference to returning an unusable pointer when practical, but given how far the authors of the Standard went to allow unusual implementations to be considered "conforming" I don't think they intended to forbid common practices of the era such as having the heap and stack at opposite ends of the free store with the stack growing down and the heap growing up. Allowing a system with 30K of free space to run programs that needed 20K of stack and 2K of heap or programs that needed 25K of heap and 1K of stack, was useful even if--as was common--there was no way a malloc() call could know whether there would be enough stack space available to satisfy the maximum future call depth. > > I don't think anything would forbid an implementation which, when it ran > > out of memory, would suspend program execution and sound a klaxon until > > someone acquired another memory board and plugged it into an unused slot, > > whereupon it would resume program execution where it left off. It wouldn't > > matter whether the klaxon was triggered by a malloc() or by a later attempt > > to use the allocated storage. If conformance or lack thereof were made > > depend upon the behavior of a future operator who might hear the klaxon, > > that would imply that conformance would be dependent upon unknowable > > future events. ... > > Whether or not the operator ever adds the requested memory has no affect on > conformance. Suspending operations until the memory is added is perfectly > acceptable. If malloc() gave up waiting for the operator to add the memory, and > either a) returned a non-null pointer which cannot, in fact, be safely used or > b) abnormally terminates the program, those would render the implementation > non-conforming, but returning a null pointer would be perfectly acceptable. Consider that the Standard says nothing about what level of subroutine nesting an implementation must support, but running out of stack is UB. Are there any particular cases where a call to malloc() would be guaranteed to complete without running out of stack? Again, quality-of-implementation issue versus requirement. > However, that's not particularly relevant to the question at hand. The fact > that it has a way of reporting an inability to fulfill the request means it's > not conforming if it responds to that inability by any method other than > returning a null pointer. However, it's fully conforming if it either returns a > null pointer or waits until the memory is installed before returning a non-null > pointer that can safely be used, no matter how long it takes to decide which of > those two options to perform. The intention of the Standard is to give wide latitude; for many cases described by the Standard it really would not be practical to regard failure-reporting mechanisms as anything other than advisory. Otherwise, the only question is whether would be better for platforms that cannot support those mechanisms have implementations which are described as conforming but do not support those mechanisms, or for the platforms to simply not support any conforming implementations.
[toc] | [prev] | [next] | [standalone]
| From | Geoff <geoff@invalid.invalid> |
|---|---|
| Date | 2016-10-31 13:01 -0700 |
| Message-ID | <3u6f1c1o5eimjgronqsr29je2d9k1tunoa@4ax.com> |
| In reply to | #95276 |
On Tue, 25 Oct 2016 22:32:25 +0800, "Mr. Man-wai Chang"
<toylet.toylet@gmail.com> wrote:
>On 10/25/2016 1:30 PM, Chris M. Thomasson wrote:
>> Calling free() is just prudent, and the right thing to do. Windows will
>> free resources after the program has ended... But, what if you are
>> creating a program that is designed to run for very long periods of
>> time? You do not want it to crap out at some random point because you
>> forgot to clean up after yourself. Right?
>
>What would happen if someone do this:
>
>char *xx;
>while (1) {
> xx=malloc(_LARGE_NUMBER_);
> free(xx);
>}
>
>Would the operating system crash? :)
Not at all. It will generate a large number of page faults and use
some CPU time allocating and freeing memory. It will slow the system
down for users and make it nearly unusable if the number is larger
than available physical memory.
You can also non-maliciously choose _LARGE_NUMBER_ to satisfy your
program's needs and then use the allocated space, freeing it and
program termination. Some practical programs do this, then use their
own allocation scheme to parcel out memory for objects within the
program.
You can also choose _LARGE_NUMBER_ judiciously for immediate needs and
realloc() as needs increase, freeing at the end. But this practice
assumes you are using only a single object once in an application but
in actual practice a program may have many objects to be allocated
from the heap. A non-malicious programmer practicing good software
engineering would not do this.
[toc] | [prev] | [next] | [standalone]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2016-10-31 16:35 -0400 |
| Message-ID | <nv89u2$sq5$1@jstuckle.eternal-september.org> |
| In reply to | #95471 |
On 10/31/2016 4:01 PM, Geoff wrote:
> On Tue, 25 Oct 2016 22:32:25 +0800, "Mr. Man-wai Chang"
> <toylet.toylet@gmail.com> wrote:
>
>> On 10/25/2016 1:30 PM, Chris M. Thomasson wrote:
>>> Calling free() is just prudent, and the right thing to do. Windows will
>>> free resources after the program has ended... But, what if you are
>>> creating a program that is designed to run for very long periods of
>>> time? You do not want it to crap out at some random point because you
>>> forgot to clean up after yourself. Right?
>>
>> What would happen if someone do this:
>>
>> char *xx;
>> while (1) {
>> xx=malloc(_LARGE_NUMBER_);
>> free(xx);
>> }
>>
>> Would the operating system crash? :)
>
> Not at all. It will generate a large number of page faults and use
> some CPU time allocating and freeing memory. It will slow the system
> down for users and make it nearly unusable if the number is larger
> than available physical memory.
>
Not necessarily. While I agree it would use some CPU time (quite a bit,
in fact, since it is an endless loop), it may or may not generate page
faults.
The malloc() call will request a rather large block of memory from the
OS - but only the first time. free() will typically not release that
memory back to the OS (assuming it may be needed again later).
But just allocating the memory generally will not cause a page fault,
except for maybe the first and last pages, when they are accessed by
malloc() and free() to update the internal memory allocation chains.
Since there is no actually access to intermediate pages, the hardware
would not detect a page fault. Only when the pages are accessed by the
code would a page fault occur.
And on some OS's, it is possible to overcommit the memory. As a result,
a it may not be possible to allocate the page later when it is accessed,
causing even more problems (typically abnormal program termination).
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
[toc] | [prev] | [next] | [standalone]
| From | "Mr. Man-wai Chang" <toylet.toylet@gmail.com> |
|---|---|
| Date | 2016-11-01 15:31 +0800 |
| Message-ID | <nv9gc9$t69$2@dont-email.me> |
| In reply to | #95474 |
On 1/11/2016 4:35 AM, Jerry Stuckle wrote:
> The malloc() call will request a rather large block of memory from the
> OS - but only the first time. free() will typically not release that
> memory back to the OS (assuming it may be needed again later).
>
> But just allocating the memory generally will not cause a page fault,
> except for maybe the first and last pages, when they are accessed by
> malloc() and free() to update the internal memory allocation chains.
> Since there is no actually access to intermediate pages, the hardware
> would not detect a page fault. Only when the pages are accessed by the
> code would a page fault occur.
What if I change the program to:
char *xx;
while (1) {
xx=malloc(_LARGE_NUMBER_);
fill(xx, "/dev/random");
free(xx);
}
[toc] | [prev] | [next] | [standalone]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2016-11-01 11:28 -0400 |
| Message-ID | <nvaca3$l7o$2@jstuckle.eternal-september.org> |
| In reply to | #95485 |
On 11/1/2016 3:31 AM, Mr. Man-wai Chang wrote:
> On 1/11/2016 4:35 AM, Jerry Stuckle wrote:
>> The malloc() call will request a rather large block of memory from the
>> OS - but only the first time. free() will typically not release that
>> memory back to the OS (assuming it may be needed again later).
>>
>> But just allocating the memory generally will not cause a page fault,
>> except for maybe the first and last pages, when they are accessed by
>> malloc() and free() to update the internal memory allocation chains.
>> Since there is no actually access to intermediate pages, the hardware
>> would not detect a page fault. Only when the pages are accessed by the
>> code would a page fault occur.
>
> What if I change the program to:
>
> char *xx;
> while (1) {
> xx=malloc(_LARGE_NUMBER_);
> fill(xx, "/dev/random");
> free(xx);
> }
>
Then you are accessing every page, so depending on the amount of
available real memory, you may or may not get page faults.
But malloc() still only requests a block of storage from the OS the
first time through.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
[toc] | [prev] | [next] | [standalone]
| From | Geoff <geoff@invalid.invalid> |
|---|---|
| Date | 2016-10-31 12:11 -0700 |
| Message-ID | <iq5f1c58qi2f3i4fdjqfvk2am9mmou90kk@4ax.com> |
| In reply to | #95253 |
On Tue, 25 Oct 2016 12:46:53 +0800, "Mr. Man-wai Chang" <toylet.toylet@gmail.com> wrote: > >I did some Google Search on this topic. Some claimed that CPU cycles >would be wasted if you called free() in your program given the fact >Window$ would always free the memory a program requested. :) Advice like this, being free, is worth what you pay for it.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-10-31 13:08 -0700 |
| Message-ID | <3f35f54a-3a0c-4379-a29c-1b18ebf8aac1@googlegroups.com> |
| In reply to | #95464 |
On Monday, October 31, 2016 at 2:11:59 PM UTC-5, Geoff wrote: > On Tue, 25 Oct 2016 12:46:53 +0800, "Mr. Man-wai Chang" wrote: > >I did some Google Search on this topic. Some claimed that CPU cycles > >would be wasted if you called free() in your program given the fact > >Window$ would always free the memory a program requested. :) > > Advice like this, being free, is worth what you pay for it. If the large amounts of a program's storage have been swapped out to disk, calling "free()" upon that storage will likely result in the system having to swap it back in (possibly forcing something else to get swapped out). If the application quits without calling "free" upon the storage, there will never be any need to read those blocks from disk, nor swap anything else out to make room for them. Having a build-time or run-time option to control whether storage will be explicitly freed or simply abandoned is probably the best approach. In a debug build, it can be useful to keep track of how many things are allocated and how many are freed; if the numbers match, there are no leaks. On the other hand, from a production-usage standpoint, bringing in pages just before a program shuts down so they can be made available for "malloc" calls that are never going to happen, is simply a waste of time.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-10-23 21:35 +0100 |
| Message-ID | <874m426bx5.fsf@bsb.me.uk> |
| In reply to | #95194 |
"Mr. Man-wai Chang" <toylet.toylet@gmail.com> writes: > My old school C programming told me to always clean up malloc() with > corresponding calls to free() when my program exited. A slightly better rule is to free memory when you don't need it anymore. For simple programs, that is almost always just before it exits, but it may not always be quite so simple. > Is it safe to assume that VC++ in Visual Studio 2013 would always free > all memory allocated by a C program, that I don't need to free them > myself? > > Or is it actually the function of Window$ the OS? It's the OS that reclaims the storage when a program ends. Some very simple OSes don't do that, but anything you are likely to encounter these days will. Given that, it's reasonable to ask why one should bother to free memory within the program. There are two main reasons. The first is that if you free memory as soon as you can, your program may be able to handle larger data sets. These days that may seem to be less of an issue, but even if you can handle all of the data you want, being parsimonious with memory will reduce the impact of your program on the system as a whole. The second reason is that programs have a habit of becoming part of larger programs. A program that responds to a network request by performing some computation, may one day become part a loop that endlessly responds to such requests. If you get into the habit of freeing unused memory as soon as you are able to, no work is needed when this change takes place. It may be that this sort of planning for an uncertain future runs counter to the modern philosophy of agile programming, but I think that freeing memory is often so simple that getting into the habit of doing it hardly counts as adding a currently unneeded feature. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | "Mr. Man-wai Chang" <toylet.toylet@gmail.com> |
|---|---|
| Date | 2016-10-25 12:49 +0800 |
| Message-ID | <numo7a$2l9$4@dont-email.me> |
| In reply to | #95201 |
On 10/24/2016 4:35 AM, Ben Bacarisse wrote: > The first is that if you free memory as soon as you can, your program > may be able to handle larger data sets.... > The second reason is that programs have a habit of becoming part of > larger programs. A program that responds to a network request by > performing some computation, may one day become part a loop that > endlessly responds to such requests.... These are indeed two strongest reasons to carefully manage malloc() memory in the program. -- @~@ Remain silent! Drink, Blink, Stretch! Live long and prosper!! / v \ Simplicity is Beauty! /( _ )\ May the Force and farces be with you! ^ ^ (x86_64 Ubuntu 9.10) Linux 2.6.39.3 不借貸! 不詐騙! 不援交! 不打交! 不打劫! 不自殺! 請考慮綜援 (CSSA): http://www.swd.gov.hk/tc/index/site_pubsvc/page_socsecu/sub_addressesa
[toc] | [prev] | [next] | [standalone]
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web