Runtime stack allocation

K

kid joe

Hi all,

I'm using a temporary buffer to transfer some data and would rather
not allocate it on the heap. The problem is that the size of the
buffer is only known upon entry into the function that utilizes it and
I'd rather not waste space or dynamically allocate on the heap (since
it doesn't need to persist). Now I'm planning on utilizing inline
assembly to modify the stack pointer directly to allocate the space I
need.

Here's an example:

void doSomeStuff(unsigned size) {
char* rawData;
//INLINED (Intel p4 assembly)
//sub esp, dword ptr [size]
//mov dword ptr [rawData], esp

//do some stuff with the temporary buffer, using rawData to access
it

//INLINED (Intel p4 assembly)
//add esp, dword ptr [size]

}

This should just work, right? Or are there any odd quirks that I should be
aware of that I may not have thought of?
 
S

santosh

kid said:
Hi all,

I'm using a temporary buffer to transfer some data and would rather
not allocate it on the heap. The problem is that the size of the
buffer is only known upon entry into the function that utilizes it and
I'd rather not waste space or dynamically allocate on the heap (since
it doesn't need to persist). Now I'm planning on utilizing inline
assembly to modify the stack pointer directly to allocate the space I
need.

IMHO using either a VLA or alloca() is infinitely preferable to messing
with the stack pointer directly. Of the two I'd chose VLAs when it is
available. At least it is standard. If not I'd take alloca() or even
use the heap before going for the sort of trickery you illustrate.
 
W

Wolfgang Draxinger

kid said:
Hi all,

I'm using a temporary buffer to transfer some data and would
rather not allocate it on the heap. The problem is that the
size of the buffer is only known upon entry into the function
that utilizes it and I'd rather not waste space or dynamically
allocate on the heap (since it doesn't need to persist). Now
I'm planning on utilizing inline assembly to modify the stack
pointer directly to allocate the space I need.

No need for inline assembler, if there's some portable function,
that will do the trick. However I can only advise, not to use
it. Most implementations of malloc are efficient enough to
compete in performance with...

alloca

Wolfgang Draxinger
 
K

Keith Thompson

kid joe said:
I'm using a temporary buffer to transfer some data and would rather
not allocate it on the heap. The problem is that the size of the
buffer is only known upon entry into the function that utilizes it and
I'd rather not waste space or dynamically allocate on the heap (since
it doesn't need to persist). Now I'm planning on utilizing inline
assembly to modify the stack pointer directly to allocate the space I
need.
[...]

My advice: allocate it using malloc() (on the "heap") anyway, and call
free() when you're done with it.

There is no portable and reliable way to do temporary allocations on
the "stack". (The C standard doesn't even guarantee that there is a
"stack" in the sense you probably mean.)

By using assembly language, you limit yourself to a single platform.
 
S

Stephen Sprunk

kid said:
I'm using a temporary buffer to transfer some data and would rather
not allocate it on the heap. The problem is that the size of the
buffer is only known upon entry into the function that utilizes it and
I'd rather not waste space or dynamically allocate on the heap (since
it doesn't need to persist). Now I'm planning on utilizing inline
assembly to modify the stack pointer directly to allocate the space I
need.

Here's an example:

void doSomeStuff(unsigned size) {
char* rawData;
//INLINED (Intel p4 assembly)
//sub esp, dword ptr [size]
//mov dword ptr [rawData], esp

//do some stuff with the temporary buffer, using rawData to access
it

//INLINED (Intel p4 assembly)
//add esp, dword ptr [size]

}

This should just work, right? Or are there any odd quirks that I should be
aware of that I may not have thought of?

Well, assuming you want to limit your code to only working on a
particular platform or processor, and you know your code won't conflict
with the compiler's optimizations...

malloc()/free() should be fast enough, even if it doesn't "feel" like
the right tool for the job. If not, can you use a VLA? If not, does
your system offer alloca()? Any of those are better than subverting the
compiler (and portability) and confusing people who will read your code
later by using inline assembly.

S
 
K

Keith Thompson

Stephen Sprunk said:
malloc()/free() should be fast enough, even if it doesn't "feel" like
the right tool for the job. If not, can you use a VLA? If not, does
your system offer alloca()? Any of those are better than subverting
the compiler (and portability) and confusing people who will read your
code later by using inline assembly.

Yes, but alloca() isn't much better. Quoting the alloca man page on
one system:

The alloca function is machine and compiler dependent. On many
systems its implementation is buggy. Its use is discouraged.

On many systems alloca cannot be used inside the list of
arguments of a function call, because the stack space reserved
by alloca would appear on the stack in the middle of the space
for the function arguments.

And VLAs have the drawback that there's no way to check whether the
allocation succeeded.

Use malloc(), and remember to free() the space when you're done with
it.
 
K

kid joe

kid said:
I'm using a temporary buffer to transfer some data and would rather
not allocate it on the heap. The problem is that the size of the
buffer is only known upon entry into the function that utilizes it and
I'd rather not waste space or dynamically allocate on the heap (since
it doesn't need to persist). Now I'm planning on utilizing inline
assembly to modify the stack pointer directly to allocate the space I
need.

Here's an example:

void doSomeStuff(unsigned size) {
char* rawData;
//INLINED (Intel p4 assembly)
//sub esp, dword ptr [size]
//mov dword ptr [rawData], esp

//do some stuff with the temporary buffer, using rawData to access
it

//INLINED (Intel p4 assembly)
//add esp, dword ptr [size]

}

This should just work, right? Or are there any odd quirks that I should be
aware of that I may not have thought of?

Well, assuming you want to limit your code to only working on a
particular platform or processor, and you know your code won't conflict
with the compiler's optimizations...

malloc()/free() should be fast enough, even if it doesn't "feel" like
the right tool for the job. If not, can you use a VLA? If not, does
your system offer alloca()? Any of those are better than subverting the
compiler (and portability) and confusing people who will read your code
later by using inline assembly.

Thanks for the replies! After doing some research, I can confirm that this
is a solution that most C compilers support (pretty much 99% of all
compilers in current use today).

void *alloca(size_t size) - allocates a block of <size> bytes on the
stack from and returns a pointer to the start of the block, the block
is automatically freed upon return from the function it was called in
(in most implementations)

Here's a slightly informative documentation of one compiler's
implementation:
http://www.datafocus.com/docs/man3/alloca.3.asp

Note that anyone using this should investigate how their compiler
implements alloca(), as it can get sticky when using it within loops
and if statements (due to scoping). Some compilers will release the
memory upon leaving scope (loop-safe), while others will release the
memory upon leaving the function it is called in (can cause stack
bloating when used within loops).

Hope this is helpful for all those who may want to do the same thing.
This function was what I was exactly looking for - rather than
complaining about this being off topic, infer based upon what I was
trying to do that I was looking for C solution to stack allocation and
was going towards the inline assembly route.

From the poor ability of inference in here, it seems the majority of
you would be better suited for the legal profession rather than
engineering profession - I've seen similar attitudes in many posts
here, whats the deal with trying to be as useless as possible?
 
S

santosh

kid said:
[...]
Well, assuming you want to limit your code to only working on a
particular platform or processor, and you know your code won't
conflict with the compiler's optimizations...

malloc()/free() should be fast enough, even if it doesn't "feel" like
the right tool for the job. If not, can you use a VLA? If not, does
your system offer alloca()? Any of those are better than subverting
the compiler (and portability) and confusing people who will read
your code later by using inline assembly.

Thanks for the replies! After doing some research, I can confirm that
this is a solution that most C compilers support (pretty much 99% of
all compilers in current use today).

void *alloca(size_t size) - allocates a block of <size> bytes on the
stack from and returns a pointer to the start of the block, the block
is automatically freed upon return from the function it was called in
(in most implementations)

Here's a slightly informative documentation of one compiler's
implementation:
http://www.datafocus.com/docs/man3/alloca.3.asp

Note that anyone using this should investigate how their compiler
implements alloca(), as it can get sticky when using it within loops
and if statements (due to scoping). Some compilers will release the
memory upon leaving scope (loop-safe), while others will release the
memory upon leaving the function it is called in (can cause stack
bloating when used within loops).

Hope this is helpful for all those who may want to do the same thing.
This function was what I was exactly looking for - rather than
complaining about this being off topic, infer based upon what I was
trying to do that I was looking for C solution to stack allocation and
was going towards the inline assembly route.

Curious, but why do you insist so on "stack allocation"? Is it to avoid
remembering to free later? Is this function speed critical?
From the poor ability of inference in here, it seems the majority of
you would be better suited for the legal profession rather than
engineering profession - I've seen similar attitudes in many posts
here, whats the deal with trying to be as useless as possible?

Not at all. Notice that several respondents did point out to you the
option of alloca and of VLAs. In engineering or science it pays to be
as thourough as possible.
 
K

Kenny McCormack

kid joe said:
Hope this is helpful for all those who may want to do the same thing.
This function was what I was exactly looking for - rather than
complaining about this being off topic, infer based upon what I was
trying to do that I was looking for C solution to stack allocation and
was going towards the inline assembly route.

From the poor ability of inference in here, it seems the majority of
you would be better suited for the legal profession rather than
engineering profession - I've seen similar attitudes in many posts
here, whats the deal with trying to be as useless as possible?

Welcome to clc! Hope you enjoy your stay.

My own view is that the clc culture is much more like the Church and
organized religion (which is to say, total scum) rather than the legal
profession. It is an insult to the legal profession to compare it to clc.

And yes, like the Church, they have perfected the art of being useless
to a high art form.
 
N

Nick Keighley

why?

void process_stuff (size_t buffer_size)
{
char *buffer;
if ((buffer = malloc(buffer_size)) == NULL)
exit (EXIT_FAILURE);

do_stuff(buffer);
free(buffer);
}


malloc()ed stuff doesn't have to persist.



that *really* sounds like you're going to use assembler...

Here's an example:
void doSomeStuff(unsigned size) {
char* rawData;
//INLINED (Intel p4 assembly)
//sub esp, dword ptr [size]
//mov dword ptr [rawData], esp

//do some stuff with the temporary buffer, using rawData to access
it
//INLINED (Intel p4 assembly)
//add esp, dword ptr [size]
}
This should just work, right? Or are there any odd quirks that I should be
aware of that I may not have thought of?
Well, assuming you want to limit your code to only working on a
particular platform or processor, and you know your code won't conflict
with the compiler's optimizations...
malloc()/free() should be fast enough, even if it doesn't "feel" like
the right tool for the job.

hello! Did you read that bit!

or this?


note alloca() is non-standard, often not implemented and often buggy.
Read some Unix man pages. Why use a buggy non-portable solution when
a portable solution (malloc()) is available? is malloc() too slow?
Is malloc() not available? Are you afraid of fragmentaion?

Thanks for the replies! After doing some research, I can confirm that this
is a solution that most C compilers support (pretty much 99% of all
compilers in current use today).

show your figures.

void *alloca(size_t size) - allocates a block of <size> bytes on the
stack from and returns a pointer to the start of the block, the block
is automatically freed upon return from the function it was called in
(in most implementations)

AND IT'S OFTEN BROKEN

Here's a slightly informative documentation of one compiler's
implementation:http://www.datafocus.com/docs/man3/alloca.3.asp

Note that anyone using this should investigate how their compiler
implements alloca(), as it can get sticky when using it within loops
and if statements (due to scoping). Some compilers will release the
memory upon leaving scope (loop-safe), while others will release the
memory upon leaving the function it is called in (can cause stack
bloating when used within loops).

so you have to do that every time you change compilers.
Maybe every time you upgrade the compiler or library...

Note alloca is sometimes in conflict with the compiler


Hope this is helpful for all those who may want to do the same thing.
This function was what I was exactly looking for - rather than
complaining about this being off topic, infer based upon what I was
trying to do that I was looking for C solution to stack allocation and
was going towards the inline assembly route.

but WHY
From the poor ability of inference in here, it seems the majority of
you would be better suited for the legal profession rather than
engineering profession - I've seen similar attitudes in many posts
here, whats the deal with trying to be as useless as possible

well to me it looks like you have the poor engineering approach.
You reject a solution out of hand and would rather use non-portable
functions than standard ones. There's a reason alloca() isn't in the
standard library.

I've never understood the "Oh please help me. Oh you are stupid"
attitude.
 
R

Roland Pibinger

No need for inline assembler, if there's some portable function,
that will do the trick. However I can only advise, not to use
it. Most implementations of malloc are efficient enough to
compete in performance with...

alloca

The following (not particularly elegant) solution provides an
optimization for some cases. It uses two functions with automatic
arrays (one should be sufficient in practice) and one with dynamic
allocation.


static void doSomeStuffImp(char* buf, unsigned size) {
// implementation
}


static void doSomeStuff256(unsigned size) {
char buf[256];
doSomeStuffImp(buf, size);
}

static void doSomeStuff1024(unsigned size) {
char buf[1024];
doSomeStuffImp(buf, size);
}

static void doSomeStuffMalloc(unsigned size) {
// ...
}


void doSomeStuff(unsigned size) {
if(size <= 256) {
doSomeStuff256(size);
} else if(size <= 1024) {
doSomeStuff1024(size);
} else {
doSomeStuffMalloc(size);
}
}
 

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,770
Messages
2,569,586
Members
45,092
Latest member
vinaykumarnevatia1

Latest Threads

Top