Dynamic memory allocation with static pointer variable

Discussion in 'C Programming' started by Shivanand Kadwadkar, Dec 25, 2010.

  1. 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
    Shivanand Kadwadkar, Dec 25, 2010
    #1
    1. Advertising

  2. Shivanand Kadwadkar

    Eric Sosman Guest

    On 12/25/2010 8:26 AM, Shivanand Kadwadkar wrote:
    > 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.

    --
    Eric Sosman
    lid
    Eric Sosman, Dec 25, 2010
    #2
    1. Advertising

  3. Shivanand Kadwadkar

    Seebs Guest

    On 2010-12-25, Shivanand Kadwadkar <> wrote:
    > 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
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Dec 25, 2010
    #3
  4. Shivanand Kadwadkar

    Nobody Guest

    On Sat, 25 Dec 2010 21:38:21 +0000, Richard Harter wrote:

    > 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.
    Nobody, Dec 25, 2010
    #4
  5. Shivanand Kadwadkar

    Tobias Blass Guest

    On Sun, 26 Dec 2010, christian.bau wrote:

    >On Dec 25, 10:21 pm, Nobody <> wrote:
    >
    >> 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();
    >>         }

    >
    >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)
    Tobias Blass, Dec 26, 2010
    #5
  6. Shivanand Kadwadkar

    Seebs Guest

    On 2010-12-26, christian.bau <> wrote:
    > That is if saving to type three characters is more important to you
    > than readable code. Pointers don't have a "truth value".


    They do in C.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Dec 26, 2010
    #6
  7. On 25 Dec 2010 19:12:27 GMT, Seebs <> wrote:

    > On 2010-12-25, Shivanand Kadwadkar <> wrote:
    > > 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.
    >

    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'.
    David Thompson, Jan 4, 2011
    #7
  8. Shivanand Kadwadkar

    Seebs Guest

    On 2011-01-04, David Thompson <> wrote:
    > On 25 Dec 2010 19:12:27 GMT, Seebs <> wrote:
    >> 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.


    Quite right! This is what I get for oversimplifying.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Jan 4, 2011
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. s.subbarayan

    Dynamic memory allocation and memory leak...

    s.subbarayan, Mar 18, 2005, in forum: C Programming
    Replies:
    10
    Views:
    681
    Eric Sosman
    Mar 22, 2005
  2. Ken
    Replies:
    24
    Views:
    3,839
    Ben Bacarisse
    Nov 30, 2006
  3. Replies:
    53
    Views:
    2,991
    David Thompson
    Feb 26, 2007
  4. chris
    Replies:
    6
    Views:
    974
    chris
    Oct 28, 2005
  5. Replies:
    7
    Views:
    786
    cr88192
    May 9, 2008
Loading...

Share This Page