Dynamic memory allocation with static pointer variable

  • Thread starter Shivanand Kadwadkar
  • Start date
S

Shivanand Kadwadkar

Case 1:Error:initializer element is not constant
static char *p =(char*)malloc(10);

Case 2:
static char *p ;
p= (char*)malloc(10);


Any idea why i am getting error in case 1 and why not in case 2
 
E

Eric Sosman

Case 1:Error:initializer element is not constant
static char *p =(char*)malloc(10);

Case 2:
static char *p ;
p= (char*)malloc(10);


Any idea why i am getting error in case 1 and why not in case 2

Case 1 is an initialization; case 2 is an assignment.

Roughly speaking, initialization happens when a variable is
created. Creation of `static' variables occurs before any program
code executes, so the initializer's value must be obtainable without
running any executable code. That's why you can't initialize a
`static' variable with the value of a function: You'd have to call
the function and execute its body, and you can't execute code before
code executes.[*]

The lines of case 2 are inside a function (if they were not, the
compiler would have complained). As in case 1 the `static' variable
is created before the program starts, and since no explicit initializer
is given the variable is initialized with "the right kind of zero," in
this case a NULL. That's a constant value, which can be calculated
without running any code, so all is well. When your program starts
running, it (presumably) calls the function containing these lines,
and then the assignment calls the malloc() function to get a value.
Calling functions once the program is running is perfectly all right,
as is assigning their values to variables.

Incidentally, the `(char*)' casts are unnecessary.

[*] Some C-related languages allow initialization to execute
code, but this is by no means a straightforward matter; it is fraught
with complication. For example, consider the apparently simple

int f(void), g(void);
static int fvalue = f();
static int gvalue = g();

Seems easy? Well, what if

int f(void) { return gvalue + 1; }
int g(void) { return fvalue + 2; }

? The outcome now depends on whether f() or g() executes first, and
whichever it is will "see" the other's variable in an incompletely
initialized state. Languages that permit this sort of thing have
(and need) dauntingly complex rules to determine what happens; C
loses some power by forbidding such initializations, but manages to
do without the considerable baggage of all those rules.
 
S

Seebs

Case 1:Error:initializer element is not constant
static char *p =(char*)malloc(10);
Case 2:
static char *p ;
p= (char*)malloc(10);
Any idea why i am getting error in case 1 and why not in case 2

Yes. Case 1's code is wrong, case 2's code is right.

Specifically: For a "static" variable, the initializer's value must
be computed at *compile* time, because no initialization code is actually
executed. The initialization happens exactly once, before your program
starts running. This means it must be constant.

In the second case, you are not using an initializer, but an assignment
statement, which executes every time you reach this point in the code.

Example:

#include <stdio.h>

int main(void) {
foo();
foo();
}

static int foo() {
static int a = 3;
static int b;

b = 4;

printf("a, b: %d, %d\n", a, b);
a = 0;
b = 0;
}

Assuming I didn't make any typos, this will print:
a, b: 3, 4
a, b: 0, 4

The initialization of a to 3 happens once before the program starts, and
thereafter, a just keeps whatever value you assign to it. By contrast,
the assignment to b is executed every time you enter foo(), so even though
b was set to 0 at the end of the first call, it is initialized to 4 again
on the second call.

Also, don't cast the return value from malloc(). This isn't exactly "wrong",
but it is nearly always a bad idea, so don't do it.

-s
 
N

Nobody

A common way to deal with dynamically
initializing static variables is to have an initialization section and
an initialized flag. Thus:
static int initialized = 0;
static char *p = 0;

if (!initialized) {
p = malloc(10); /* No cast needed */
initialized = 1;
}

For pointers which are "never" null, you'd normally just use the truth
value of the pointer, i.e.:

if (!p) {
p = malloc(10);
if (!p) abort();
}

Also, an explicit "= 0" is redundant for static variables.
 
T

Tobias Blass

That is if saving to type three characters is more important to you
than readable code. Pointers don't have a "truth value".
Actually pointers _do_ have a truth value. !p is an often used
expression to say "If p has no value"(is NULL). I think !text is just as
readable as !text_has_value or !text_initialized. Furthermore you see
this idiom in many other source codes, so it's important to know what it
means( and then you can use it yourself as well)
 
D

David Thompson

Yes. Case 1's code is wrong, case 2's code is right.

Specifically: For a "static" variable, the initializer's value must
be computed at *compile* time, because no initialization code is actually
executed. The initialization happens exactly once, before your program
starts running. This means it must be constant.
Not quite. static (allocation and) initialization occurs before
(observable) program startup, but not necessarily at compile time.
In particular you can do things like:
char x;
...
char *y = &x;
either in one translation unit (aka source file or module) or split
across multiple such, and that initialization is usually determined at
link time, which is usually after compile time, sometimes long after.
It could even be done at load time.

ObCLC: this is represented in the standard by the difference between
the strict restrictions on a 'constant expression' in general, and the
slightly weaker restrictions on an 'address constant'.
 
S

Seebs

Not quite. static (allocation and) initialization occurs before
(observable) program startup, but not necessarily at compile time.

Quite right! This is what I get for oversimplifying.

-s
 

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

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top