11

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.

6 Answers 6

22
static int *p = NULL;
if(!p) p = (int *)malloc(sizeof(int));
Sign up to request clarification or add additional context in comments.

2 Comments

This doesn't need two variables, and is better than the accepted answer because of that.
@JonathanLeffler I agree, although my answer is still valuable since it's more general - works for cases without a designated null value.
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.

6 Comments

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.
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.
@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.
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.
Yep, you happened to assume exactly what the OP didn't say, so you got it right. Silly me, answering the question actually asked. :-)
|
5

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

static int p[1];

3 Comments

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.
Then you really are allocating at runtime, and you need malloc(), not an initializer. Those are two different things.
Yes, but this is what the OP asked for: allocating at runtime, only once, for a static variable.
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.

Comments

0

malloc() will call the system call internally (in unix its sbrk()) to get the memory block which is greater in size than requested. Later if the user needs more memory then malloc() will give from the extra chunk that it got.

Comments

-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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.