Memory allocated during run time

S

Sortie

srand(time(NULL));
int size=rand();
printInteger(size);
char a[size];
printf("%d", sizeof a);

Since the memory needed for a is unknown until run time, is it
allocated dynamically, as if it was from malloc? If so, do I need
to call free() when I'm done with it?
 
S

Sortie

srand(time(NULL));
int size=rand();
printInteger(size);
char a[size];
printf("%d", sizeof a);

Since the memory needed for a is unknown until run time, is
it allocated dynamically, as if it was from malloc? If so,
do I need to call free() when I'm done with it?

printInteger(x) is just an alias for printf("%d",x ), I forgot to
change it.
 
B

Ben Bacarisse

Richard Heathfield said:
Sortie said:
srand(time(NULL));
int size=rand();
printInteger(size);
char a[size];
printf("%d", sizeof a);

Since the memory needed for a is unknown until run time, is it
allocated dynamically, as if it was from malloc?

Presumably you have a C99 compiler (in C90 the above is a syntax
error). In C99, the memory for variable length arrays (VLAs) is
obviously not allocated statically (because the amount of memory
needed is not known at compilation time); nevertheless, it is not, in
your words, "as if it was from malloc". Specifically...
If so, do I need
to call free() when I'm done with it?

...you do *not* need to free() it when you're done with it. It will
disappear when control flow exits the enclosing block in which it is
created.

Nit: I know what you mean, but some people get confused by this. If,
after the array definition, you call a function (for example) control
flow "exits" the block that contains the definition, but the object
does not get destroyed. Your word "exit" carries more meaning than
just "leaves".

I usually say "when the flow of control reaches the end of the block
(or function) that contains the definition" with the proviso that it
is understood that break, continue and return act like jumps to the
end of the block or function in which they occur.
 
B

Barry Schwarz

srand(time(NULL));
int size=rand();
printInteger(size);
char a[size];
printf("%d", sizeof a);

sizeof will not evaluate to an int. If you have a full C99 compiler,
use %zu. Otherwise, cast the value to your choice of type and use the
corresponding conversion specification.
Since the memory needed for a is unknown until run time, is it
allocated dynamically, as if it was from malloc? If so, do I need
to call free() when I'm done with it?

As others have noted, no. Even if your particular implementation
happens to invoke malloc as part of defining the array:

Assuming so is an unnecessary portability restriction.

There is obviously more information associated with the array
since sizeof cannot determine the amount of memory allocated in a
normal call to malloc but can here. realloc, and possible free, would
have to be expanded to deal with this extra information.
 
D

David Resnick

srand(time(NULL));
int size=rand();
printInteger(size);
char a[size];
printf("%d", sizeof a);

sizeof will not evaluate to an int.  If you have a full C99 compiler,
use %zu.  Otherwise, cast the value to your choice of type and use the
corresponding conversion specification.


Since the memory needed for a is unknown until run time, is it
allocated dynamically, as if it was from malloc? If so, do I need
to call free() when I'm done with it?

As others have noted, no.  Even if your particular implementation
happens to invoke malloc as part of defining the array:

It seems to me like using malloc would be quite difficult here,
perhaps I'm just not seeing how it would work? If you have a VLA
still in scope in a function, and call some other function that does a
longjmp, by what means would the VLA be freed if it was allocated with
malloc? The original function never "returns". This is analogous to
the issue in C++, where local objects are never destroyed if a longjmp
is called before they leave scope (making longjmp difficult to use in C
++ or mixed C and C++ programs). Seems like non-portable magic is
more likely used (e.g. alloca or similar might work).

-David
 
R

Richard Tobin

As others have noted, no. Even if your particular implementation
happens to invoke malloc as part of defining the array:
[/QUOTE]
It seems to me like using malloc would be quite difficult here,
perhaps I'm just not seeing how it would work? If you have a VLA
still in scope in a function, and call some other function that does a
longjmp, by what means would the VLA be freed if it was allocated with
malloc? The original function never "returns".

We're talking about how the implementation does it, so it can use
arbitrary magic. In this case the magic might be unwinding
the stack during longjmp() (as some implementations already do) and
having some kind of marker in the stack frame indicating that a
free() was necessary. Alternatively there might be a separate
stack just containing information about VLAs.

-- Richard
 
S

Stephen Sprunk

David said:
It seems to me like using malloc would be quite difficult here, perhaps
I'm just not seeing how it would work? ... Seems like non-portable magic
is more likely used (e.g. alloca or similar might work).

I suspect that VLAs are typically implemented via alloca() or a
functional equivalent. If alloca() had been standardized, we wouldn't
need VLAs in the first place; if you have alloca(), a VLA adds nothing
except saving the programmer a few keystrokes and adding complicated
corner cases to the Standard.

S
 
K

Keith Thompson

Stephen Sprunk said:
I suspect that VLAs are typically implemented via alloca() or a
functional equivalent. If alloca() had been standardized, we wouldn't
need VLAs in the first place; if you have alloca(), a VLA adds nothing
except saving the programmer a few keystrokes and adding complicated
corner cases to the Standard.

alloca() has its own complicated corner cases. Its behavior is
typically undefined if the allocation fails (VLAs have the same
problem), and it can misbehave if it's called within an argument
list. On at least some implementations, it's impossible to take
the address of the function; if it were to be standardized, that
could be addressed by specifying that it's a macro.
 
B

Beej Jorgensen

Stephen Sprunk said:
if you have alloca(), a VLA adds nothing except saving the programmer a
few keystrokes and adding complicated corner cases to the Standard.

And easier allocation of multidimensional arrays of various types for
use in numerical applications, which is the main reason they're there.

-Beej
 
C

Chris McDonald

Stephen Sprunk said:
I suspect that VLAs are typically implemented via alloca() or a
functional equivalent. If alloca() had been standardized, we wouldn't
need VLAs in the first place; if you have alloca(), a VLA adds nothing
except saving the programmer a few keystrokes and adding complicated
corner cases to the Standard.

For the beginning programmer, VLAs are far easier to comprehend,
and they may be introduced in a book or course well before pointers need
to be understood.
 
E

Eric Sosman

Stephen said:
I suspect that VLAs are typically implemented via alloca() or a
functional equivalent. If alloca() had been standardized, we wouldn't
need VLAs in the first place; if you have alloca(), a VLA adds nothing
except saving the programmer a few keystrokes and adding complicated
corner cases to the Standard.

Quoth the Rationale,

"Some implementations provide a function, often called
alloca, which allocates the requested object from automatic
storage; and the object is automatically freed when the
calling function exits. Such a function is not efficiently
implementable in a variety of environments, so it was not
adopted in the Standard."

It does not claim that VLA's *are* efficiently implementable on
systems where alloca() is not, but ...

Also quoth the Rationale,

"C99 adds a new array type called a variable length array
type. The inability to declare arrays whose size is known
only at execution time was often cited as a primary deterrent
to using C as a numerical computing language. Adoption of
some standard notion of execution time arrays was considered
crucial for C’s acceptance in the numerical computing world."

Personally, I think C's part in the battle for the hearts and minds
of numericists is over, and that C should face up to its defeat,
bind up its wounds, and try to slip away from the field lest a
still-healthy combatant bayonet it twixt guggle and zatch. The
Committee evidently felt otherwise, and have bandaged C with the
VLA, armed it with _Complex, given it FP_CONTRACT as first aid, and
encouraged it to make yet one more assault (however restrict-ed)
on the foe's redoubts. Fortran to the left of C, Matlab to the
right of -- oh, sorry; I got carried away on the wild wet waves
(stop that!!!) of metaphor.
 
P

Peter Nilsson

Richard Heathfield said:
Sortie said:
srand(time(NULL));
int size=rand();
printInteger(size);
char a[size];
printf("%d", sizeof a);

...in C90 the above is a syntax error).

Nit: I don't believe it violates syntax since C's grammar
is context insensitive. Although it certainly violates a
constraint.
 
K

Keith Thompson

Peter Nilsson said:
Richard Heathfield said:
Sortie said:
srand(time(NULL));
int size=rand();
printInteger(size);
char a[size];
printf("%d", sizeof a);

...in C90 the above is a syntax error).

Nit: I don't believe it violates syntax since C's grammar
is context insensitive. Although it certainly violates a
constraint.

The C90 grammar for a compound-statement is:

compound-statement
{ declaration-list[opt] statement-list[opt] }

declaration-list
declaration
declaration-list declaration

statement-list
statement
statement-list statement

So yes, the above is (was?) a syntax error in C90.
 
R

Richard Tobin

srand(time(NULL));
int size=rand();
printInteger(size);
char a[size];
printf("%d", sizeof a);
...in C90 the above is a syntax error).
[/QUOTE]
Nit: I don't believe it violates syntax since C's grammar
is context insensitive.

C90's production for compound-statement is

{ declaration-list? statement-list? }

so it does violate the grammar. C doesn't attempt to enforce, say,
declaration before use in the grammar, but it does (pre-C99) enforce
the relative ordering of declarations and statements in the grammar.

-- Richard
 
R

Richard Bos

Keith Thompson said:
A can of worms I was trying hard not to re-open.

The can of worms is whether it is or was a syntax error in C. I don't
think anybody can seriously deny that it still is one in C90.

Richard
 
J

jameskuyper

Richard said:
The can of worms is whether it is or was a syntax error in C. I don't
think anybody can seriously deny that it still is one in C90.

The can of worms that Keith was referring to is the one implicit in
the "is (was)" part of his earlier statement: de-jure, C99 is the
current standard; de-facto, C90 is the current standard.
 
K

Keith Thompson

jameskuyper said:
The can of worms that Keith was referring to is the one implicit in
the "is (was)" part of his earlier statement: de-jure, C99 is the
current standard; de-facto, C90 is the current standard.

Exactly. (Though the de facto "standard" seems to be something like
C90 plus long long plus // comments.)
 
S

Stephen Sprunk

Keith said:
alloca() has its own complicated corner cases. Its behavior is
typically undefined if the allocation fails (VLAs have the same
problem),

It's hard for alloca() to fail, unlike malloc() et al; the only real
failure mode is stack overflow, and the Standard already has some very
loose guarantees with regards to the amount of memory available for
automatic variables (including, but not limited to, VLAs).

In theory, an implementation _could_ return NULL if stack overflow would
occur, which isn't possible with a VLA or other excessively-large
automatic variables. Every few months, we a newbie asking here about
why a 1MB+ auto array crashes his program...
and it can misbehave if it's called within an argument list.

I wasn't aware of that case; it never would have occurred to me to use
it there, though now that I think of it I can see why someone might try
it. VLAs obviously don't have that problem. Hmm.
On at least some implementations, it's impossible to take
the address of the function; if it were to be standardized, that
could be addressed by specifying that it's a macro.

.... as is done for several other standard functions/macros. It'd be
tough to implement alloca() as a real function; it practically begs to
be built-in, not even a macro.

S
 
R

Richard Bos

jameskuyper said:
The can of worms that Keith was referring to is the one implicit in
the "is (was)" part of his earlier statement: de-jure, C99 is the
current standard; de-facto, C90 is the current standard.

Yes, I know. But he wasn't talking about the current Standard. He was
explicitly discussing _C90_. Now, regardless of which is the _current_
Standard, C90 still is C90.

Richard
 

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,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top