“int *nums = {5, 2, 1, 4}” causes a segmentation fault

There is a (stupid) rule in C saying that any plain variable may be initialized with a brace-enclosed initializer list, just as if it was an array.

For example you can write int x = {0};, which is completely equivalent to int x = 0;.

So when you write int *nums = {5, 2, 1, 4}; you are actually giving an initializer list to a single pointer variable. However, it is just one single variable so it will only get assigned the first value 5, the rest of the list is ignored (actually I don’t think that code with excess initializers should even compile with a strict compiler) – it does not get written to memory at all. The code is equivalent to int *nums = 5;. Which means, numsshould point at address 5.

At this point you should already have gotten two compiler warnings/errors:

  • Assigning integer to pointer without a cast.
  • Excess elements in initializer list.

And then of course the code will crash and burn since 5 is most likely not a valid address you are allowed to dereference with nums[0].

As a side note, you should printf pointer addresses with the %p specifier or otherwise you are invoking undefined behavior.


I’m not quite sure what you are trying to do here, but if you want to set a pointer to point at an array, you should do:

int nums[] = {5, 2, 1, 4};
int* ptr = nums;

// or equivalent:
int* ptr = (int[]){5, 2, 1, 4};

Or if you want to create an array of pointers:

int* ptr[] = { /* whatever makes sense here */ };

EDIT

After some research I can say that the “excess elements initializer list” is indeed not valid C – it is a GCC extension.

The standard 6.7.9 Initialization says (emphasis mine):

2 No initializer shall attempt to provide a value for an object not
contained within the entity being initialized.

/–/

11 The initializer for a scalar shall be a single expression,
optionally enclosed in braces.
The initial value of the object is that
of the expression (after conversion); the same type constraints and
conversions as for simple assignment apply, taking the type of the
scalar to be the unqualified version of its declared type.

“Scalar type” is a standard term referring to single variables that are not of array, struct or union type (those are called “aggregate type”).

So in plain English the standard says: “when you initialize a variable, feel free to toss in some extra braces around the initializer expression, just because you can.”

Leave a Comment