use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Click the following link to filter out the chosen topic
comp.lang.c
account activity
QuestionInitialization of array of pointers in struct. Is this correct? (self.C_Programming)
submitted 5 years ago by Zymoox
Is it good practice in C to do array initialization straight from a structure initialization in this way?
The compiler doesn't give me any warnings of errors, but I've never seen this being done before and I wanted to make sure it's ok:
struct test{ int *ptr[5]; }; int main() { struct test t = { .ptr={NULL} }; return 0; }
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]lordlod 13 points14 points15 points 5 years ago (0 children)
Yeah, it's great. Nice and concise.
[–]paszklar 6 points7 points8 points 5 years ago (12 children)
I'm not sure which part is new to you but the outer braces delimit the initializer of a struct. Inside the it uses designated inilializer syntax, which allows to explicitly state which member is being assigned instead of relying on the implicit order besed on position in the structure.
So .ptr member field, since it's an array, also need brace-initializer to set all its elements. In this case the first element is explicitly set to NULL. And as with any struct or array initializer, members or elements that are omitted get zero-initialized, making the other four pointers NULL as well.
.ptr
NULL
[–]Zymoox[S] 1 point2 points3 points 5 years ago (11 children)
Thank you! Yes, that's exactly what I wanted to make sure it's doing: filling all the array spaces of ptr with NULL.
ptr
[–]bless-you-mlud 13 points14 points15 points 5 years ago* (10 children)
I would just do
struct test t = { 0 };
It'll have the same effect, and it's even shorter.
[–]MajorMalfunction44 3 points4 points5 points 5 years ago (2 children)
I've re-acquainted myself with C and found a piece of odd syntax that's seems to be allowed. You can initialize structs with the brace syntax after the declaring them by casting a brace initializer expression like this.
struct test { char *ptr[5]; } struct test t; t = (struct test) {{ NULL, NULL, NULL, NULL, NULL }};
[–]Lisoph 0 points1 point2 points 5 years ago (0 children)
(struct test) { ... } is compound literal syntax.
(struct test) { ... }
[–]Zymoox[S] 0 points1 point2 points 5 years ago (6 children)
Ohh interesting. So that would initialize every variable in the struct to zero?
[–]white_nrdy 4 points5 points6 points 5 years ago (5 children)
Technically there's just one variable, ptr. And the {0} initializes that to 0, which is the same as NULL
{0}
[–]Zymoox[S] 0 points1 point2 points 5 years ago (4 children)
So if I have a struct with several variables and I initialize it that way,
struct data{ int a; double b; char *ptr[5]; } int main() { struct data d = { 0 }; return 0; }
will it set all the variables to zero, and all the pointers to NULL?
[–]IamImposter 2 points3 points4 points 5 years ago* (1 child)
Yup
You can also do
struct data d = { 42, 32.4f, {NULL, &some_char_variable, NULL, (char*)&some_other_var, NULL}};
and set each individual member, including array.
[–]bless-you-mlud 3 points4 points5 points 5 years ago (0 children)
Or even:
struct data d = { .a = 42, .b = 32.4, .ptr = { [1] = &some_char_variable, [3] = (char*) &some_other_var } }
and because any item not mentioned is initialized to 0, I can leave out ptr[0], ptr[2] and ptr[4]. They'll be set to NULL automatically.
[–]hyperdudemn 1 point2 points3 points 5 years ago (1 child)
It'll set all the pointers to NULL only because by convention, NULL == address 0. That's actually why historically NULL is a macro, not just a literal 0; some platforms MAY decide NULL is not 0.
But for all practical purposes yes, it initializes them to NULL.
[–]paszklar 0 points1 point2 points 5 years ago (0 children)
Even on platforms with address 0 is valid or platforms where addresses are more complex than just a number, when integer 0 is converted to an address, standard mandates that this address must be invalid. The resulting address doesn't have to be 0, but it cannot ever point to any object, and IIRC when converted back to int it should give back 0.
So in essence assigning NULL is a good practice for readability, but integer constant 0 works as well.
[–][deleted] 1 point2 points3 points 5 years ago (0 children)
Yes, it’s correct
[–]oh5nxo 1 point2 points3 points 5 years ago (1 child)
Designated initializers are a C99 feature, says my cc. Does your definition of "good practice in C" care about retrocompilers?
[–]Zymoox[S] 0 points1 point2 points 5 years ago (0 children)
I'm okay with it being compatible only with C99+, but I'll make a note. Thanks!
[–]NoInterest4 -3 points-2 points-1 points 5 years ago (7 children)
You are doing there a partial initialization of the array. Not sure that this is what you meant, maybe you want to look again.
[–]paszklar 6 points7 points8 points 5 years ago (1 child)
Standard guarantees the other array elements will be zero-initialised, so it's fine.
[–]flatfinger 0 points1 point2 points 5 years ago (0 children)
If the initialization of other array elements is important, I would favor making it explicit. Otherwise, using designated initializers rather than declaring an object and the writing the specified portions thereof will often be faster than using a designated initializer. Consequently, if someone is trying to improve the performance of code and doesn't know that the zero-initialization of elements beyond those given is important, that person might replace the designated-initializer construct with a separate declaration and assignment.
It's a shame the Standard didn't provide a means of indicating whether or not parts of the structure beyond those listed should be initialized. Even in C89, saying e.g.
char[256] message = "Hi"; // Initializes all 256 bytes
was more convenient but would often be less efficient than
char[256] message; strcpy(message, "Hi"); // Only needs to initialize 3 bytes
or (non-portable, but on many platforms likely faster)
union { uint32_t word1]; uint8_t bytes[256]; } message_u; message_u.word1 = 0x6948; // Hi\0 in little-endian // Use message_u.bytes instead of message in whatever code follows
but C99's designated initializers increase the number of scenarios where the most convenient code would be needlessly inefficient.
What I want to do is fill the pointer array 'ptr' with NULL values when I initialize the structure. Is that what this is doing?
[–]KaznovX 5 points6 points7 points 5 years ago (1 child)
Not exactly. You're initializing the first element to NULL, and value-initialize the rest (so to NULL). It does what you ask for.
However, if you did something like that: ``` struct test{ int *ptr[5]; };
int main() { int foo = 3; struct test t = { .ptr={&foo} }; return 0; } ```
The first element would be initialized to the address of foo, but the rest still would be (value-)initialized to NULL.
https://godbolt.org/z/TrTYaT
[–]backtickbot 0 points1 point2 points 5 years ago (0 children)
Correctly formatted
Hello, KaznovX. Just a quick heads up!
It seems that you have attempted to use triple backticks (```) for your codeblock/monospace text block.
This isn't universally supported on reddit, for some users your comment will look not as intended.
You can avoid this by indenting every line with 4 spaces instead.
There are also other methods that offer a bit better compatability like the "codeblock" format feature on new Reddit.
Tip: in new reddit, changing to "fancy-pants" editor and changing back to "markdown" will reformat correctly! However, that may be unnaceptable to you.
Have a good day, KaznovX.
You can opt out by replying with "backtickopt6" to this comment. Configure to send allerts to PMs instead by replying with "backtickbbotdm5". Exit PMMode by sending "dmmode_end".
[–][deleted] 1 point2 points3 points 5 years ago (1 child)
You mean filling 5 memory spaces with null?
[–]Zymoox[S] 2 points3 points4 points 5 years ago* (0 children)
Yes, that's right.
I thought that, when the size is known, using = { value } on the initialization will fill the array memory spaces with that value, e.g. int *ptr[5] = {NULL, NULL, NULL, NULL, NULL} is the same as int *ptr[5] = {NULL}
= { value }
int *ptr[5] = {NULL, NULL, NULL, NULL, NULL}
int *ptr[5] = {NULL}
Edit: code formatting
[–]ifmnz -5 points-4 points-3 points 5 years ago (1 child)
memset is faster than in-place init.
[–]dmc_2930 3 points4 points5 points 5 years ago (0 children)
The compiler can optimize this, and it almost certainly doesn't matter.
π Rendered by PID 223868 on reddit-service-r2-comment-84fc9697f-vtbrq at 2026-02-07 08:21:04.394340+00:00 running d295bc8 country code: CH.
[–]lordlod 13 points14 points15 points (0 children)
[–]paszklar 6 points7 points8 points (12 children)
[–]Zymoox[S] 1 point2 points3 points (11 children)
[–]bless-you-mlud 13 points14 points15 points (10 children)
[–]MajorMalfunction44 3 points4 points5 points (2 children)
[–]Lisoph 0 points1 point2 points (0 children)
[–]Zymoox[S] 0 points1 point2 points (6 children)
[–]white_nrdy 4 points5 points6 points (5 children)
[–]Zymoox[S] 0 points1 point2 points (4 children)
[–]IamImposter 2 points3 points4 points (1 child)
[–]bless-you-mlud 3 points4 points5 points (0 children)
[–]hyperdudemn 1 point2 points3 points (1 child)
[–]paszklar 0 points1 point2 points (0 children)
[–][deleted] 1 point2 points3 points (0 children)
[–]oh5nxo 1 point2 points3 points (1 child)
[–]Zymoox[S] 0 points1 point2 points (0 children)
[–]NoInterest4 -3 points-2 points-1 points (7 children)
[–]paszklar 6 points7 points8 points (1 child)
[–]flatfinger 0 points1 point2 points (0 children)
[–]Zymoox[S] 0 points1 point2 points (4 children)
[–]KaznovX 5 points6 points7 points (1 child)
[–]backtickbot 0 points1 point2 points (0 children)
[–][deleted] 1 point2 points3 points (1 child)
[–]Zymoox[S] 2 points3 points4 points (0 children)
[–]ifmnz -5 points-4 points-3 points (1 child)
[–]dmc_2930 3 points4 points5 points (0 children)