Allocate memory to a static variable only once

Possible duplicate:
Defining global variables using a non-constant initializer

I have this code:

#include <stdio.h> #include <stdlib.h> int foo (int num, int i) { static int* array = malloc(sizeof(int)); // ERROR HERE!!! printf("%d", array[i]); return 0; } int main(int argc, char *argv[]) { int i; for (i = 0; i < 2; i++) { foo(i, i); } return 0; } 

I save the code as the source file c, I can not work? error prompt :

 gcc -O2 -Wall test.c -lm -o test test.c:4:1: error: initializer element is not constant Compilation exited abnormally with code 1 at Sat Jan 05 21:33:56 

However, I save it as a source file in C ++, it works fine. What for? is there anyone can explain this to me?

+4
source share
4 answers

C and C ++ standards handle object initialization with static storage duration in different ways. C ++ allows both static initialization (i.e., initialization with a constant) and dynamic initialization (i.e., initialization with a mutable expression), while C only allows static initialization, i.e. With constant expressions.

The relevant part of the C ++ standard is 6.7.4:

Zero initialization (8.5) of all local objects with static storage duration (3.7.1) is performed before any other initialization. A local object of type POD (3.9) with a static storage duration, initialized by constant expressions, is initialized before its block is entered first. [...] Otherwise, such an object is initialized, the first time control passes through its declaration; such an object is considered initialized after completion of its initialization. (highlighted by me)

C ++ requires an additional โ€œaccountโ€ to start the dynamic part of your initializer (ie calling malloc ) only once. There is no such โ€œdynamicโ€ provision in the C standard:

Before starting the program, all objects with static storage must be initialized (set to their initial values). All expressions in the initializer for an object with a duration of static storage must be constant expressions or string literals.

In the absence of concurrency, you can rewrite the code for use with C as follows:

 int foo (int num, int i) { static int* array = NULL; if (!array) array = malloc(sizeof(int)); // No error printf("%d", array[i]); return 0; } 

Now your code is responsible for accounting: it checks the array for NULL before performing the allocation.

+2
source

You cannot initialize static objects with mutable initializers in C.

 static int* array = malloc(sizeof(int)); ^ must be a constant 

From standard C:

(C99, 6.7.8p4) "All expressions in the initializer for an object with a duration of static storage must be constant expressions or string literals."

+3
source

C (unlike C ++) does not allow initialization of variables of static duration with non-constant values.

 static int* array = malloc(sizeof(int)); // ERROR HERE!!! 

C99 Standard: Section 6.7.8:

All expressions in the initializer for an object with a duration of static storage must be constant expressions or string literals.

+1
source

This is ilegal in C, but OK in C ++, they are different

Instead, write as follows:

 static int* array = NULL; if (array == NULL) array = malloc(sizeof(int)); 
+1
source

All Articles