VLA feature of C99 vs malloc

M

Marc Boyer

Le 18-12-2006 said:
Suppose
int size = INT_MAX / 8;
char a[size];
are declared to use the feature of variable lenght array(VLA) in C99.
With appropriate #includes, when this code is run, segmentation fault
occurs in Red Hat enterprise Linux with 32-bit compiler.

Howver if
char * str = (char *)malloc(INT_MAX);
is declared and run , with appropriate headers, malloc is able to
return INT_MAX bytes.(this is 8 times more than the previous VLA
declaration)

Does this mean that malloc should be preferred over variable length
arrays, for huge memory allocations ?

This limitation is platform-specific, and C99 does not states
so. But, in many platform, you can found this kind of limitations.
Does the standard specify any limit regarding the size of VLA.

Not to my knowledge.

Marc Boyer
 
S

subramanian

Suppose
int size = INT_MAX / 8;
char a[size];
are declared to use the feature of variable lenght array(VLA) in C99.
With appropriate #includes, when this code is run, segmentation fault
occurs in Red Hat enterprise Linux with 32-bit compiler.

Howver if
char * str = (char *)malloc(INT_MAX);
is declared and run , with appropriate headers, malloc is able to
return INT_MAX bytes.(this is 8 times more than the previous VLA
declaration)

Does this mean that malloc should be preferred over variable length
arrays, for huge memory allocations ?
Does the standard specify any limit regarding the size of VLA.
 
K

Kohn Emil Dan

Suppose
int size = INT_MAX / 8;
char a[size];
are declared to use the feature of variable lenght array(VLA) in C99.
With appropriate #includes, when this code is run, segmentation fault
occurs in Red Hat enterprise Linux with 32-bit compiler.

Howver if
char * str = (char *)malloc(INT_MAX);
is declared and run , with appropriate headers, malloc is able to
return INT_MAX bytes.(this is 8 times more than the previous VLA
declaration)

Does this mean that malloc should be preferred over variable length
arrays, for huge memory allocations ?

I think your problem has little to do with VLAs. Your problem is that you
allocate a large automatic object. Most likely replacing the VLA with a
normal automatic C array such as:

char a[INT_MAX/8];

will yield the same problem. In general automatic objects are allocated on
the stack, and platforms place various retrictions on the size of the
stacks. For example Windows places an upper limit of 1 megabyte, the
kernel-mode stack of linux is limited to 8 or 4 kilobytes. Moreover, some
system administrators place per-process limits on the stack size. Bottom
line: If you want to allocate large objects, use *alloc(), not automatic
local variables.

Emil
 
J

Jack Klein

Suppose
int size = INT_MAX / 8;
char a[size];
are declared to use the feature of variable lenght array(VLA) in C99.
With appropriate #includes, when this code is run, segmentation fault
occurs in Red Hat enterprise Linux with 32-bit compiler.

Howver if
char * str = (char *)malloc(INT_MAX);
is declared and run , with appropriate headers, malloc is able to
return INT_MAX bytes.(this is 8 times more than the previous VLA
declaration)

Does this mean that malloc should be preferred over variable length
arrays, for huge memory allocations ?
Does the standard specify any limit regarding the size of VLA.

VLAs are a useless and unsafe feature added by C99, unless you know
they are always going to be very small.

They are a bone thrown to those rabid users of non-standard extensions
like alloca(), who insist that their programs can't possibly survive
the overhead of true memory allocation.

Like the extensions it replaces, VLAs suffer from the same problem.
They are limited by the environment's bounds on the size of automatic
allocation.

To prove this to your self, replace the line defining size as an int
with a macro defining it to the same value. If the program fails with
the macro because you implementation does not allow you an automatic
allocation that large, it will fail with the VLA.

The only difference is that you can verify whether malloc() and its
relatives succeed or fail, but on many platforms allocating too large
a VLA results in immediate program termination.
 
J

jacob navia

Jack Klein a écrit :
VLAs are a useless and unsafe feature added by C99, unless you know
they are always going to be very small.

When you write
void fn(int m)
{
double tab[CONSTANT];
}

You do the same thing. All C users know by experience
that the allocations in the stack should be relatively
small.

The advantage with the C99 construct is that you allocate
exaclt what it is needed, not more, and not less. You *could*
allocate the same buffer with malloc obviously, but with
a lot more overhead.

jacob
 
R

Random832

2006-12-18 said:
To prove this to your self, replace the line defining size as an int
with a macro defining it to the same value. If the program fails with
the macro because you implementation does not allow you an automatic
allocation that large, it will fail with the VLA.

You think the compiler can tell you at compile time that an automatic
allocation, even without being a VLA, will fail?
 
M

Malcolm

jacob navia said:
Jack Klein a écrit :
VLAs are a useless and unsafe feature added by C99, unless you know
they are always going to be very small.

When you write
void fn(int m)
{
double tab[CONSTANT];
}

You do the same thing. All C users know by experience
that the allocations in the stack should be relatively
small.

The advantage with the C99 construct is that you allocate
exaclt what it is needed, not more, and not less. You *could*
allocate the same buffer with malloc obviously, but with
a lot more overhead.
I use salloc() in this case, the name is short for "stack allocate".

double stack[MAX];
double *stacktop;

void *salloc(int N)
{
double *answer = stacktop;
stacktop += (N + sizeof(double) -1)/sizeof(double);
return answer;
}

void sfree(void *ptr)
{
stacktop = ptr;
}

Very fast, and trivial to implement. You can easily add safety checks. The
only problem is that the local stack might not be in the cache, and memory
cannot be recycled for non-salloc() functions.
 
K

Kohn Emil Dan

On Mon, 18 Dec 2006, Jack Klein wrote:

VLAs are a useless and unsafe feature added by C99, unless you know
they are always going to be very small.

They are a bone thrown to those rabid users of non-standard extensions
like alloca(), who insist that their programs can't possibly survive
the overhead of true memory allocation.

Actually one good reason to using VLAs is that code using
multi-dimensional arrays (technically arrays of arrays) whose indices
depend on the function parameters is much more readable, than what can be
achieved using malloc() or the non-standard alloca(). But I agree, it's
way to easy to screw things up with stack overflows.

<snipped>
Emil
 
K

Kohn Emil Dan

jacob navia said:
Jack Klein a écrit :
I use salloc() in this case, the name is short for "stack allocate".

double stack[MAX];
double *stacktop;

void *salloc(int N)
{
double *answer = stacktop;
stacktop += (N + sizeof(double) -1)/sizeof(double);
return answer;
}

void sfree(void *ptr)
{
stacktop = ptr;
}

Very fast, and trivial to implement. You can easily add safety checks. The
only problem is that the local stack might not be in the cache, and memory
cannot be recycled for non-salloc() functions.

In addition to that your code is not reentrant. It won't work well in
multi-threaded environments. VLAs do.


Emil


 
D

David Geering

Actually one good reason to using VLAs is that code using
multi-dimensional arrays (technically arrays of arrays) whose indices
depend on the function parameters is much more readable, than what can be
achieved using malloc() or the non-standard alloca(). But I agree, it's
way to easy to screw things up with stack overflows.

<snipped>
Emil

I've never fiddled around much with anything other than malloc. I've always used
malloc for multi-dimensional arrays and to me, since it has been the only
way I've been doing it, it makes sense and I can read it fine; but now
that you mention it, it is probably a nightmare for anyone else to follow.
 
W

websnarf

Jack said:
Suppose
int size = INT_MAX / 8;
char a[size];
are declared to use the feature of variable lenght array(VLA) in C99.
With appropriate #includes, when this code is run, segmentation fault
occurs in Red Hat enterprise Linux with 32-bit compiler.

Howver if
char * str = (char *)malloc(INT_MAX);
is declared and run , with appropriate headers, malloc is able to
return INT_MAX bytes.(this is 8 times more than the previous VLA
declaration)

Does this mean that malloc should be preferred over variable length
arrays, for huge memory allocations ?
Does the standard specify any limit regarding the size of VLA.

VLAs are a useless and unsafe feature added by C99, unless you know
they are always going to be very small.

They are a bone thrown to those rabid users of non-standard extensions
like alloca(), who insist that their programs can't possibly survive
the overhead of true memory allocation.

Huh? So you've never measured the performance of malloc before? The
most useful malloc()'s I've ever seen (the ones with best long term
*sustained* performance) are around 50 clocks overhead per call.
Compare that to a stack pointer subtract -- which will cost at most 1
clock of real performance.

Now, I think C99 is full of it for other reasons, so my solution to
this is to commonly write alternative malloc()'s from scratch with all
sorts of functional differences (usually pool based with a "freeall"
function.) Straight C sucks for ADTs, if for no other reason, that the
cost of a malloc per atomic piece is huge. Going to pool based
allocators lets me bring the overhead down to just a few clocks (a
call, a couple of predicted ifs and adds ...) since the overhead of
"free" is amortized over all the atoms -- so this is an acceptable
stand in, but the C standard is of no help here.

In terms of a combination of speed and simplicity, being able to grab
dynamic memory from the stack is far more convenient. You don't need
to call free, so its like garbage collection without any of the
negative effects of it. (Though, it has new problems, like exposing
stack size considerations, as the OP has stepped into.)
 
E

E. Robert Tisdale

subramanian said:
Suppose
int size = INT_MAX / 8;
char a[size];
are declared to use the feature of variable lenght array(VLA) in C99.
With appropriate #includes, when this code is run, segmentation fault
occurs in Red Hat enterprise Linux with 32-bit compiler.

Howver if
char * str = (char *)malloc(INT_MAX);
is declared and run , with appropriate headers, malloc is able to
return INT_MAX bytes.(this is 8 times more than the previous VLA
declaration)

Does this mean that malloc should be preferred over variable length
arrays, for huge memory allocations ?
Does the standard specify any limit regarding the size of VLA.
> cat f.h
#ifndef F_H
#define F_H
void f(int size);
#endif//F_H
> cat f.c
#include "f.h"

void f(int size) {
char a[size];
a[0] = '0';
return;
}
> cat main.c
#include <limits.h>
#include "f.h"

int main(int argc, char* argv[]) {
const int size = INT_MAX/8;
f(size);
return 0;
}
 

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,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top