10

I'm trying to initiate a static variable (inside a function) with malloc in C, but I'm getting the "initializer not constant error". I know that I can't initiate a static with non constants in C, but can anyone think of a solution? I need the code to have the same effect as this:

static int *p = (int *)malloc(sizeof(int));

Is there a trick/workaround?

EDIT: I have a function that is called every time a flag goes high. In this function, I'm creating and starting a new thread. I declare a pointer to a struct and use malloc to allocate memory then pass this pointer to the thread. Then the function returns control. When I re-enter the function, the thread that I opened initially will still be running and I want to be able to access the memory region that I originally passed to the thread. That's why I need a static so that I can malloc on the first call and then use the same address on subsequent calls. This way I can get info from the thread. All this to avoid using global variables.

Elazar
  • 20,415
  • 4
  • 46
  • 67
Arash Fotouhi
  • 1,933
  • 2
  • 22
  • 43

5 Answers5

22
static int *p = NULL;
if(!p) p = (int *)malloc(sizeof(int));
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • 4
    This doesn't need two variables, and is better than the accepted answer because of that. – Jonathan Leffler Sep 25 '14 at 06:38
  • 1
    @JonathanLeffler I agree, although my answer is still valuable since it's more general - works for cases without a designated null value. – Elazar Sep 23 '17 at 22:43
9

Assuming you want function-static variables:

int foo(void) {
    static int b=1;
    static int *p;
    if (b) {
        p =  malloc(sizeof(int));
        b = 0;
    }
    ...
}

You can use NULL value for p as a check, as long as you know it will never be NULL after the first call.

Remember to check for errors in malloc; it is a runtime allocation, and should also be freed when it will not be needed anymore.

Elazar
  • 20,415
  • 4
  • 46
  • 67
  • Thanks for the solution! Essentially what I was trying to do is have malloc allocate once and keep the same address for subsequent calls. This does exactly that. – Arash Fotouhi May 23 '13 at 22:45
  • How will this even compile? That "if..." will have to be placed inside a function like main(), in which case you have ordinary runtime allocation. – Lee Daniel Crocker May 23 '13 at 22:45
  • @LeeDanielCrocker - I assumed trivially this is inside a function. and yes, of course it is an ordinary runtime allocation - this is what the OP asked for. – Elazar May 23 '13 at 22:50
  • Sounds like you're talking about the static declaration being inside a function. Your original question didn't say that; you asked about a file-level static. Yes, this answer will work for statics declared inside a function. – Lee Daniel Crocker May 23 '13 at 22:51
  • Yep, you happened to assume exactly what the OP didn't say, so you got it right. Silly me, answering the question actually asked. :-) – Lee Daniel Crocker May 23 '13 at 22:54
  • This code is not thread-safe and is thus very bad programming practice, especially for use in libraries. A much better approach would be `static int foo, *p = &foo;` unless you *really* need for the memory to be allocated by `malloc`. Of course, in any case, you should probably be protecting access to static objects with appropriate mutexes, or better yet, not using any non-const static objects at all. – R.. GitHub STOP HELPING ICE May 24 '13 at 00:36
5

malloc() is only used to allocate memory at runtime. Static variables are initialized at sompile time. You want:

static int p[1];
Lee Daniel Crocker
  • 12,927
  • 3
  • 29
  • 55
  • This will not help if you want the allocation to depend on the parameters for the first call. VLA may help though, but I can't see how exactly. – Elazar May 23 '13 at 22:29
  • Then you really are allocating at runtime, and you need `malloc()`, not an initializer. Those are two different things. – Lee Daniel Crocker May 23 '13 at 22:35
  • Yes, but this is what the OP asked for: allocating at runtime, only once, for a static variable. – Elazar May 23 '13 at 22:36
1

If it is file static, then you should provide a public function in that file that will initialize that static.

void initialize () {
    if (p == 0) p = malloc(sizeof(*p));
}

Or, you can use a static function instead of a static variable. It costs you a check per access though:

static int * p () {
    static int * p_;
    return p_ ? p_ : (p_ = malloc(sizeof(*p_)));
}

For an integer type, this seems a little silly, but if p were some more complex type that required a more complicated initialization sequence than just the return value of malloc(), then it might make sense to have something like this.

jxh
  • 69,070
  • 8
  • 110
  • 193
-2

C can't do that. C++ can with static constructors.

You could do the allocation first thing in main(), or in any other function that is called before your pointer is needed.

While nonportable, some executable formats such as the Classic Mac OS' Code Fragment Manager support initialization/termination entry points. The CFM initialization was used for C++ static construction. If the executable format on your platform supports an initialization entry point, you could use that.

Mike Crawford
  • 2,232
  • 2
  • 18
  • 28