When to use automatic variables and when to use malloc

  • Thread starter Jorge Peixoto de Morais Neto
  • Start date
J

Jorge Peixoto de Morais Neto

I was reading the code of FFmpeg and it seems that they use malloc
just too much. The problems and dangers of malloc are widely known.
Malloc also has some overhead (although I don't know what is the
overhead of automatic variable sized arrays, I suspect it is smaller
than that of malloc), although I'm not too worried about it.

I was thinking that, with C99's variable length arrays, malloc
shouldn't be needed most of the time. But I'm not sure if it is
appropriate to declare everything as automatic variables, specially
for huge variables.

1-) When is it appropriate to use automatic variables?*

2-) If the problem is size, then what is the threshold?**

*I already know that we should be aware of the duration of the
variable, such as not to use an automatic variable as a buffer inside
a function, and then return the buffer. By the time the function
returns, the buffer is gone.

** Of course, I know this varies. But, given a reasonable system (say,
my Athlon XP 2600+ with 512 MB of RAM) and a reasonable OS (such as
GNU/Linux, and let's also include MS Windows because it is common),
can you give me an order of magnitude?

PS: I have googled first, and searched within this newsgroup before,
and I only found one previous discussion. It missed the point. People
kept arguing that automatic variables are fixed size, which is not
true anymore. People also kept arguing that malloc tells you when
there is not enough memory (by returning NULL) and allows you to do
something. I don't care much about it, since in the vast majority of
cases I just close the program when malloc fails. I have even written
a wrapper, so I don't have to check the pointer:

inline void *smalloc(size_t size){
void * const ptr=malloc(size);
if (ptr==NULL){
fputs("Function ",stderr);
fputs(__func__,stderr);
fputs(" called malloc and malloc returned NULL.\n",stderr);
perror(NULL);
exit(ENOMEM); // exit ou abort?
} else {
return ptr;
}
}

By the way, in the above case should I have used abort() or is exit()
ok? From the respective manual pages, I can't tell.
 
B

Ben Pfaff

Jorge Peixoto de Morais Neto said:
I was reading the code of FFmpeg and it seems that they use malloc
just too much. The problems and dangers of malloc are widely known. [...]
I was thinking that, with C99's variable length arrays, malloc
shouldn't be needed most of the time. But I'm not sure if it is
appropriate to declare everything as automatic variables, specially
for huge variables.

What "dangers" of malloc are alleviated by using variable length
arrays? I suspect that forgetting to deallocate the memory block
is the only one.
 
R

Roberto Waltman

Jorge Peixoto de Morais Neto said:
I was reading the code of FFmpeg and it seems that they use malloc
just too much. The problems and dangers of malloc are widely known.
Malloc also has some overhead (although I don't know what is the
overhead of automatic variable sized arrays, I suspect it is smaller
than that of malloc), although I'm not too worried about it.

There are three different areas where you could talk about malloc's
overhead:

(a) Allocation time: This can be problematic, (in the general case) it
is not deterministic, can change from one pass through a function to
the next, can increase over time as memory becomes fragmented, etc.
Can be partially solved using your own memory allocators.
The time necessary to allocate stack space for local variables can be
zero.
For any particular scenario: Benchmark, measure.

(b) Memory overhead: there is a finite amount of storage associated
with each memory block 'malloced', used for internal bookkeeping.
No such overhead for automatic variables. (In common implementations)
For any particular scenario: Benchmark, measure.

(c) Run-time access overhead. Implementation dependent. For most
common architectures there is no noticeable difference in the time
required to access either, but there could be *huge* differences
either way.
The stack and heap areas (yes, I know they do not officially exist,)
may reside in physical devices with different access speeds, (on-chip
stack vs. heap in external RAM, for example), the CPU instruction set
may have weaker instructions for addressing stack based variables, or
weak instructions for accessing general memory (as when all load/store
operations must go trough a dedicated register that becomes a
bottleneck,) and so on.
(It was common in C compilers for low end 8-bit processors (which
typically have weak relative-addressing instructions) to have a
command line optimization switch that would force them to process all
automatic variables as if they were static.)
For any particular scenario: Benchmark, measure.
I was thinking that, with C99's variable length arrays, malloc
shouldn't be needed most of the time.

Assuming C99 features are available. That is not always the case.
But I'm not sure if it is
appropriate to declare everything as automatic variables, specially
for huge variables.

1-) When is it appropriate to use automatic variables?*

a) Small data sizes.
b) The data should be accessible only by the function in which it
resides or functions called from it.
2-) If the problem is size, then what is the threshold?**

Depends on the system, can be as low as a few tens of bytes for small
embedded systems.
*I already know that we should be aware of the duration of the
variable, such as not to use an automatic variable as a buffer inside
a function, and then return the buffer. By the time the function
returns, the buffer is gone.

** Of course, I know this varies. But, given a reasonable system (say,
my Athlon XP 2600+ with 512 MB of RAM) and a reasonable OS (such as
GNU/Linux, and let's also include MS Windows because it is common),
can you give me an order of magnitude?

For any particular scenario: Benchmark, measure.
PS: I have googled first, and searched within this newsgroup before,
and I only found one previous discussion. It missed the point. People
kept arguing that automatic variables are fixed size, which is not
true anymore.

As mentioned above, it still is in many cases.
People also kept arguing that malloc tells you when
there is not enough memory (by returning NULL) and allows you to do
something. I don't care much about it, since in the vast majority of
cases I just close the program when malloc fails.

Would you like the people writing the code for you car's antilock
brakes to follow that approach?
I have even written
a wrapper, so I don't have to check the pointer:

inline void *smalloc(size_t size){
void * const ptr=malloc(size);
if (ptr==NULL){
fputs("Function ",stderr);
fputs(__func__,stderr);
fputs(" called malloc and malloc returned NULL.\n",stderr);
perror(NULL);
exit(ENOMEM); // exit ou abort?
} else {
return ptr;
}
}

By the way, in the above case should I have used abort() or is exit()
ok? From the respective manual pages, I can't tell.

Roberto Waltman

[ Please reply to the group,
return address is invalid ]
 
R

Richard Tobin

Ben Pfaff said:
What "dangers" of malloc are alleviated by using variable length
arrays? I suspect that forgetting to deallocate the memory block
is the only one.

And unlike malloc(), variable length arrays don't let you recover when
you run out of memory. Of course, nor do any other kind of auto
variable.

-- Richard
 
W

websnarf

Jorge Peixoto de Morais Neto said:
I was reading the code of FFmpeg and it seems that they use malloc
just too much. The problems and dangers of malloc are widely known. [...]
I was thinking that, with C99's variable length arrays, malloc
shouldn't be needed most of the time. But I'm not sure if it is
appropriate to declare everything as automatic variables, specially
for huge variables.

What "dangers" of malloc are alleviated by using variable length
arrays? I suspect that forgetting to deallocate the memory block
is the only one.

malloc returns a pointer. A variable length array, is still just
that; an array. So the common danger of using pointers versus arrays
is removed. (An array base cannot be NULL, cannot change relative to
its intended storage, and cannot be pointing to unaccessible memory.)

It also introduces a new form of risk, however. If there is no space
for such an auto array, then the program clearly exhibits UB. This is
unlike the usual circumstance for "stack overflow" due to recursion,
because those are usually quite easily debuggable. In the variable
length array case, things are arbitrarily hard because the length of
the array chosen is under runtime control.
 
E

Eric Sosman

Jorge said:
I was reading the code of FFmpeg and it seems that they use malloc
just too much. The problems and dangers of malloc are widely known.

Isn't it a shame the way people just sit on valuable
information others could benefit from? In the thirty years
I've used C, nobody -- NOBODY -- has warned me about the
"widely known" problems and dangers of malloc(). Well, you
learn something new every day.
Malloc also has some overhead (although I don't know what is the
overhead of automatic variable sized arrays, I suspect it is smaller
than that of malloc), although I'm not too worried about it.

I was thinking that, with C99's variable length arrays, malloc
shouldn't be needed most of the time. But I'm not sure if it is
appropriate to declare everything as automatic variables, specially
for huge variables.

1-) When is it appropriate to use automatic variables?*

When their duration fits the problem at hand, when they're
not unusually large, and when you know the total size at the
point of creation -- i.e., when you won't need realloc().
2-) If the problem is size, then what is the threshold?**

How high is "up?" How long is a piece of string? Or, in
more program-centric terms, how deep is the call stack?

Note that automatic variables might not reside on a stack;
smallish variables are often found in CPU registers, for example.
It's also possible that some VLA implementations just call malloc()
and free() under the covers.
*I already know that we should be aware of the duration of the
variable, such as not to use an automatic variable as a buffer inside
a function, and then return the buffer. By the time the function
returns, the buffer is gone.

** Of course, I know this varies. But, given a reasonable system (say,
my Athlon XP 2600+ with 512 MB of RAM) and a reasonable OS (such as
GNU/Linux, and let's also include MS Windows because it is common),
can you give me an order of magnitude?

As you say, "this varies." A few hundred bytes' worth of
auto variables are usually nothing to worry about; at a few KB
one should spend at least a while thinking about stack depth
(both above and below the current function); at a few tens of
KB and above it would seem more prudent to malloc().
PS: I have googled first, and searched within this newsgroup before,
and I only found one previous discussion. It missed the point. People
kept arguing that automatic variables are fixed size, which is not
true anymore. People also kept arguing that malloc tells you when
there is not enough memory (by returning NULL) and allows you to do
something. I don't care much about it, since in the vast majority of
cases I just close the program when malloc fails.

Even if all you're going to do is shut down, it's often
preferable to do a clean shutdown via exit() than to let the
host environment just rip the rug from beneath you. Would you
like the output streams flushed? Would you like the atexit()
handlers to run? If you're in an airplane, would you rather
hear the pilot say "We're running out of fuel, so we'll have
to divert to Dubuque" or "We're running out of fuel, so I'll
just dive 'er into the sod?"
I have even written
a wrapper, so I don't have to check the pointer:

inline void *smalloc(size_t size){
void * const ptr=malloc(size);
if (ptr==NULL){

Should be `ptr==NULL && size>0'.
fputs("Function ",stderr);
fputs(__func__,stderr);
fputs(" called malloc and malloc returned NULL.\n",stderr);
perror(NULL);

The `errno' value (if there was one that meant anything) may
not have survived through all those fputs() calls.
exit(ENOMEM); // exit ou abort?

Seems a poor choice of exit status (only 0, EXIT_SUCCESS,
and EXIT_FAILURE are standardized; ENOMEM looks like an `errno'
value, not like an exit status). Despite the dubious status,
though, observe the huge difference between calling exit() and
dying without a chance to "get your affairs in order."
} else {
return ptr;
}
}

By the way, in the above case should I have used abort() or is exit()
ok? From the respective manual pages, I can't tell.

It depends on the needs of the program. exit() is usually
preferable, because it will try to run atexit() handlers, flush
output streams, and so on. But if you've really run the memory
tank down to empty, a "clean" shutdown may require more than is
left -- in which case, abort() might be better.

Note that terminating on malloc() failure is not always the
only or even the best strategy available. Imagine: You are using
an editing program, and have been getting things Just Right for
the last three hours. Then you tell it to open this one last
video clip you want to use, and it goes SorryNoMemoryGoodbyeBANG!
and exits with your three hours' labor lost. Wouldn't you have
preferred that it said SorryNoMemory and kept on running, giving
you a chance to save your work?
 
W

websnarf

I was reading the code of FFmpeg and it seems that they use malloc
just too much. The problems and dangers of malloc are widely known.
Malloc also has some overhead (although I don't know what is the
overhead of automatic variable sized arrays, I suspect it is smaller
than that of malloc), although I'm not too worried about it.

In my experience, malloc + free takes an estimated total time of about
100 cycles. A compile time variable length array (such as through
C99's variable length arrays, or the function alloca() that some C
compilers support) takes about 1 or 2 total clocks to allocate then
release. So variable length arrays are certainly much faster.
I was thinking that, with C99's variable length arrays, malloc
shouldn't be needed most of the time. But I'm not sure if it is
appropriate to declare everything as automatic variables, specially
for huge variables.

C99 is a generally unrecognized, and effectively obsolete standard.
Using C99, except in limited environments and usually a restricted
subset, is possible but will almost always work against porting of
your code to other platforms.
1-) When is it appropriate to use automatic variables?*

Whenever the lifetime of the variable is equal to the scope of the
code block or function, and when the variable size is fixed at compile
time.
2-) If the problem is size, then what is the threshold?**

Even in C99 this threshold is unknown. No exceptions are thrown, no
error path, no nothing. Your just experience UB if you get it wrong.
*I already know that we should be aware of the duration of the
variable, such as not to use an automatic variable as a buffer inside
a function, and then return the buffer. By the time the function
returns, the buffer is gone.

Well yeah, that's the *major* criteria. If you variable doesn't need
to be returned (and thus is unreferenced), then make it local.
** Of course, I know this varies. But, given a reasonable system (say,
my Athlon XP 2600+ with 512 MB of RAM) and a reasonable OS (such as
GNU/Linux, and let's also include MS Windows because it is common),
can you give me an order of magnitude?

Well, most x86 compilers size the stack by criteria that is determined
by your compiler, not your underlying platform capabilities.
 
R

Richard Heathfield

Jorge Peixoto de Morais Neto said:
I was reading the code of FFmpeg and it seems that they use malloc
just too much.

If that is true, then it's a Bad Thing, on the basis that too much of
*anything* is a bad thing. But what makes you think they are using
malloc too much? What criteria are you using to make your judgement?
The problems and dangers of malloc are widely known.

The problems and dangers of malloc *misuse* are widely known, certainly.
Malloc also has some overhead (although I don't know what is the
overhead of automatic variable sized arrays, I suspect it is smaller
than that of malloc),

To which implementations does your suspicion apply, and why?
although I'm not too worried about it.

Oh, that's all right then.
I was thinking that, with C99's variable length arrays, malloc
shouldn't be needed most of the time.

C99 may be here in theory, but it'll be a while yet before it's as
widely available as C90. In any case, VLAs don't solve the problem of
building dynamic data structures that can persist after a function has
returned. Since that's 99.054% (warning: bogus statistic) of all malloc
usage, I don't think we can get rid of malloc that easily. Nor do I see
any particularly strong motivation for doing so.

People also kept arguing that malloc tells you when
there is not enough memory (by returning NULL) and allows you to do
something. I don't care much about it, since in the vast majority of
cases I just close the program when malloc fails.

No attempt at recovery? No attempt to save user data? No opportunity for
the user to close some other programs and re-try? Ouch.
I have even written
a wrapper, so I don't have to check the pointer:

Remind me never to use your software. :)

inline void *smalloc(size_t size){
void * const ptr=malloc(size);
if (ptr==NULL){
fputs("Function ",stderr);
fputs(__func__,stderr);
fputs(" called malloc and malloc returned NULL.\n",stderr);
perror(NULL);
exit(ENOMEM); // exit ou abort?
} else {
return ptr;
}
}

By the way, in the above case should I have used abort() or is exit()
ok? From the respective manual pages, I can't tell.

What advantage would abort() confer that exit() doesn't give you?
 
S

santosh

Jorge said:
I was reading the code of FFmpeg and it seems that they use malloc
just too much. The problems and dangers of malloc are widely known.

All techniques have their share of imperfections.
Malloc also has some overhead (although I don't know what is the
overhead of automatic variable sized arrays, I suspect it is smaller
than that of malloc), although I'm not too worried about it.

The Standard doesn't specify anything about the efficiency of a C
construct.
I was thinking that, with C99's variable length arrays, malloc
shouldn't be needed most of the time. But I'm not sure if it is
appropriate to declare everything as automatic variables, specially
for huge variables.

VLA are local objects. More importantly they're not supported well by
most popular C compilers.
1-) When is it appropriate to use automatic variables?*

They'd be appropriate whenever you need relatively small amounts of
storage and will only be using it from a well restricted part of your
entire programme. In other words, they would be called for whenever
you *don't* need wide access, (or scope), and a long lifetime.
2-) If the problem is size, then what is the threshold?**

That would depend upon the specific implementation and target runtime
environment. There's no clear answer. Generally above a few thousand
bytes of storage, you might want to look towards dynamically allocated
memory.

Note though that there's nothing inherent in C's specifications of
automatic objects that restricts their use for large allocation
requests. It is the stack related limitation of many widely used
architectures that make very large automatic objects infeasable or
atleast suspect.

If an implementation happens to have hundreds of megabytes set aside
for automatic objects storage, then there would be no such problems.
*I already know that we should be aware of the duration of the
variable, such as not to use an automatic variable as a buffer inside
a function, and then return the buffer. By the time the function
returns, the buffer is gone.

** Of course, I know this varies. But, given a reasonable system (say,
my Athlon XP 2600+ with 512 MB of RAM) and a reasonable OS (such as
GNU/Linux, and let's also include MS Windows because it is common),
can you give me an order of magnitude?

No. What's reasonable for one situation may not be reasonable for
another. It more important to write modularised C code than worry
about borderline situations. If you find yourself needing very large
automatic objects, (many megabytes), then you should probably rethink
the overall design of your program.
PS: I have googled first, and searched within this newsgroup before,
and I only found one previous discussion. It missed the point. People
kept arguing that automatic variables are fixed size, which is not
true anymore. People also kept arguing that malloc tells you when
there is not enough memory (by returning NULL) and allows you to do
something. I don't care much about it, since in the vast majority of
cases I just close the program when malloc fails. I have even written
a wrapper, so I don't have to check the pointer:

inline void *smalloc(size_t size){

inline would probably gain nothing.
void * const ptr=malloc(size);

It'd make more sense to make size const than ptr.
if (ptr==NULL){
fputs("Function ",stderr);
fputs(__func__,stderr);
fputs(" called malloc and malloc returned NULL.\n",stderr);
perror(NULL);

You should set errno to zero before call to malloc and use perror
before the various fputs calls or save the errno value set by malloc
locally before calling any other function. Also note that the standard
does not require malloc to set errno at all.
exit(ENOMEM); // exit ou abort?

This is a non-standard error value. Additionally other than 0,
EXIT_SUCCESS or EXIT_FAILURE, passing any other value to exit or a
return from main is not portable.
} else {
return ptr;
}
}

By the way, in the above case should I have used abort() or is exit()
ok? From the respective manual pages, I can't tell.

In general if you have no clean-up to do, i.e. all streams are closed
etc., then abort would probably be acceptable. Note that exit calls
functions registered with atexit so if you want to terminate with
executing as little code as possible, then abort is ideal.

In most situations though exit is preferrable, as you get a chance to
properly close resources.
 
U

user923005

I was reading the code of FFmpeg and it seems that they use malloc
just too much. The problems and dangers of malloc are widely known.
Malloc also has some overhead (although I don't know what is the
overhead of automatic variable sized arrays, I suspect it is smaller
than that of malloc), although I'm not too worried about it.

I was thinking that, with C99's variable length arrays, malloc
shouldn't be needed most of the time. But I'm not sure if it is
appropriate to declare everything as automatic variables, specially
for huge variables.

1-) When is it appropriate to use automatic variables?*

2-) If the problem is size, then what is the threshold?**

*I already know that we should be aware of the duration of the
variable, such as not to use an automatic variable as a buffer inside
a function, and then return the buffer. By the time the function
returns, the buffer is gone.

** Of course, I know this varies. But, given a reasonable system (say,
my Athlon XP 2600+ with 512 MB of RAM) and a reasonable OS (such as
GNU/Linux, and let's also include MS Windows because it is common),
can you give me an order of magnitude?

PS: I have googled first, and searched within this newsgroup before,
and I only found one previous discussion. It missed the point. People
kept arguing that automatic variables are fixed size, which is not
true anymore. People also kept arguing that malloc tells you when
there is not enough memory (by returning NULL) and allows you to do
something. I don't care much about it, since in the vast majority of
cases I just close the program when malloc fails. I have even written
a wrapper, so I don't have to check the pointer:

inline void *smalloc(size_t size){
void * const ptr=malloc(size);
if (ptr==NULL){
fputs("Function ",stderr);
fputs(__func__,stderr);
fputs(" called malloc and malloc returned NULL.\n",stderr);
perror(NULL);
exit(ENOMEM); // exit ou abort?
} else {
return ptr;
}

}

By the way, in the above case should I have used abort() or is exit()

Usually you only use abort() when you want to use the debugger with
it. You normally use exit() when your program cannot continue. Which
brings up an interesting question.
"What happens to your application when there is insufficient memory
for the auto allocation of the variable sized array?"
I have searched through the standard for the terms "VLA" and "variable
length array" and I do not see anything that spells out what happens
when automatic memory is exhausted.
I suspect very much that the result is simply a crash or a core dump.

So the use of VLA seems to be chiefly trading our forgetfullness to
remember to free the objects we have created for instability and a
situation that is hard to diagnose and recover from.

I was keen on them (VLAs) for a while and then it occurred to me that
the fundamental approach is severely broken. We don't have any way to
recover from a failed VLA allocation. We can at least diagnose the
problem with malloc(). If VLAs could "fail over" and use memory from
the free store when automatic memory is exhausted, they would be a lot
more useful.
ok? From the respective manual pages, I can't tell.

If you are debugging a problem, use abort(). If you are exiting the
program because you have found an error that is too serious to
continue, then use exit().

IMO-YMMV.
 
W

websnarf

Isn't it a shame the way people just sit on valuable
information others could benefit from? In the thirty years
I've used C, nobody -- NOBODY -- has warned me about the
"widely known" problems and dangers of malloc(). Well, you
learn something new every day.

You, of course, have never heard of viruses, heap overflows, double
freeing, memory leaking or information leaking. Probably because
these things don't appear in the standard and you haven't looked at
the wider world of computing since the 1970s.
 
G

Gordon Burditt

Isn't it a shame the way people just sit on valuable
You, of course, have never heard of viruses, heap overflows, double
freeing, memory leaking or information leaking. Probably because
these things don't appear in the standard and you haven't looked at
the wider world of computing since the 1970s.

And using auto arrays (especially variable-size and large) can have
problems with viruses, stack (if there is one) frame overflows,
information leaking, and stack overflow. Stack-frame-clobbering
is more popular with viruses than malloc-region-clobbering since
clobbering the return address can force a branch to someplace
specified by the virus but malloc-region-clobbering isn't guaranteed
to do that. At least with malloc() calls, it's possible to check
if you ran out of memory.
 
C

CBFalconer

You, of course, have never heard of viruses, heap overflows,
double freeing, memory leaking or information leaking. Probably
because these things don't appear in the standard and you haven't
looked at the wider world of computing since the 1970s.

I see you have been taking diplomacy lessons from Dan Pop, so you
should know where he has gone, and why he is no longer active
here. Please tell us all.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
 
K

Keith Thompson

Jorge Peixoto de Morais Neto said:
I was reading the code of FFmpeg and it seems that they use malloc
just too much. The problems and dangers of malloc are widely known. [...]
I was thinking that, with C99's variable length arrays, malloc
shouldn't be needed most of the time. But I'm not sure if it is
appropriate to declare everything as automatic variables, specially
for huge variables.

What "dangers" of malloc are alleviated by using variable length
arrays? I suspect that forgetting to deallocate the memory block
is the only one.

malloc returns a pointer. A variable length array, is still just
that; an array. So the common danger of using pointers versus arrays
is removed. (An array base cannot be NULL, cannot change relative to
its intended storage, and cannot be pointing to unaccessible memory.)
[...]

I fail to see how any danger is removed. An array name still decays
to a pointer in most contexts, and all the pitfalls of confusing
arrays and pointers (all of which can be alleviated by reading and
understanding section 6 of the comp.lang.c FAQ) are still there.
 
J

Jorge Peixoto de Morais Neto

People also kept arguing that malloc tells you when
Would you like the people writing the code for you car's antilock
brakes to follow that approach?
Good example. It reminds that a wrapper like mine should not be
blindly used. I still think it is OK to use in a lot of circustances,
though, as long as you know what you are doing.

And for the many people that said that my wrapper would do a dirty
exit: the exit() function does a lot of cleanup automatically: flushes
and closes files, removes tmpfile() temp files, executes functions
registered with atexit() and on_exit()... (this is straight from the
man page). So, I do think that in that majority of cases the wrapper
(with the corrections people suggested) is OK. Again, it should not be
blindingly used. The guy who talked about the editing program gave an
excellent example.

Oh, and thak you very much for all the responses.
 
J

Jorge Peixoto de Morais Neto

Good example. It reminds that a wrapper like mine should not be
blindly used. I still think it is OK to use in a lot of circustances,
though, as long as you know what you are doing.

And for the many people that said that my wrapper would do a dirty
exit: the exit() function does a lot of cleanup automatically: flushes
and closes files, removes tmpfile() temp files, executes functions
registered with atexit() and on_exit()... (this is straight from the
man page). So, I do think that in that majority of cases the wrapper
(with the corrections people suggested) is OK. Again, it should not be
blindingly used. The guy who talked about the editing program gave an
excellent example.

Oh, and thak you very much for all the responses.

Oh, and to make clear, I am aware that, since the program will crash
when I use too much stack, than I should not use huge variables on
stack unless I'm OK with the program crashing if there is not enough
memory. So if it would be OK to use the wrapper, it is OK to use VLA.
(from the "what happens if it crash" perspective. There are still
other perspectives.)

If I'm encoding video and there is not enough memory for and important
buffer, I can only flush the buffers, close the files and exit. The
wrapper is OK.

In the case of the antilock brake though, it is not OK.
 
J

Jorge Peixoto de Morais Neto

Isn't it a shame the way people just sit on valuable
information others could benefit from? In the thirty years
I've used C, nobody -- NOBODY -- has warned me about the
"widely known" problems and dangers of malloc(). Well, you
learn something new every day.




When their duration fits the problem at hand, when they're
not unusually large, and when you know the total size at the
point of creation -- i.e., when you won't need realloc().


How high is "up?" How long is a piece of string? Or, in
more program-centric terms, how deep is the call stack?

Note that automatic variables might not reside on a stack;
smallish variables are often found in CPU registers, for example.
It's also possible that some VLA implementations just call malloc()
and free() under the covers.



As you say, "this varies." A few hundred bytes' worth of
auto variables are usually nothing to worry about; at a few KB
one should spend at least a while thinking about stack depth
(both above and below the current function); at a few tens of
KB and above it would seem more prudent to malloc().


Even if all you're going to do is shut down, it's often
preferable to do a clean shutdown via exit() than to let the
host environment just rip the rug from beneath you. Would you
like the output streams flushed? Would you like the atexit()
handlers to run? If you're in an airplane, would you rather
hear the pilot say "We're running out of fuel, so we'll have
to divert to Dubuque" or "We're running out of fuel, so I'll
just dive 'er into the sod?"
Good point.
When I told that "If there is no memory, just let it crash" I was
think of applications like video encoding. If, at the beginning of the
encoding, a buffer cannot be allocated, the program should just exit,
and I don't care about cleanup (since we have no useful data to be
flushed). But of course, I wouldn't do this in the main encoding loop,
since there may be useful data to be flushed, so I should call exit.
Heck, it may happen that he program runs out of memory in the very
last frame of the video...

I was thinking about a specific case and spoke like if was the general
case. Sorry about that.


Should be `ptr==NULL && size>0'.


The `errno' value (if there was one that meant anything) may
not have survived through all those fputs() calls.
I had read about it today but forgot when writing the wrapper...
Thanks for reminding me
Seems a poor choice of exit status (only 0, EXIT_SUCCESS,
and EXIT_FAILURE are standardized; ENOMEM looks like an `errno'
value, not like an exit status).
Forgive my ignorance, but so what i


Despite the dubious status,
 
J

Jorge Peixoto de Morais Neto

And using auto arrays (especially variable-size and large) can have
problems with viruses, stack (if there is one) frame overflows,
information leaking, and stack overflow. Stack-frame-clobbering
is more popular with viruses than malloc-region-clobbering since
clobbering the return address can force a branch to someplace
specified by the virus but malloc-region-clobbering isn't guaranteed
to do that. At least with malloc() calls, it's possible to check
if you ran out of memory.

He meant that malloc has some dangers, not that VLAs do not.
 
J

Jorge Peixoto de Morais Neto

You made me think of another question: when a program crashes,
possibly due to lack of memory, do the OS normally flush its buffers
and close its files?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top