36

I am aware you cannot use an initialiser list for an array. However I have heard of ways that you can set an array of pointers to NULL in a way that is similar to an initialiser list.

I am not certain how this is done. I have heard that a pointer is set to NULL by default, though I do not know if this is guaranteed/ in the C++ standard. I am also not sure if initialising through the new operator compared to normal allocation can make a difference too.

Edit: I mean to do this in a header file/constructor initialisation list. I do not want to put it in the constructor, and I do not want to use a Vector.

6 Answers 6

60

In order to set an array of pointers to nulls in constructor initializer list, you can use the () initializer

struct S {
  int *a[100];

  S() : a() {
    // `a` contains null pointers 
  }
};

Unfortunately, in the current version of the language the () initializer is the only initializer that you can use with an array member in the constructor initializer list. But apparently this is what you need in your case.

The () has the same effect on arrays allocated with new[]

int **a = new int*[100]();
// `a[i]` contains null pointers 

In other contexts you can use the {} aggregate initializer to achieve the same effect

int *a[100] = {};
// `a` contains null pointers 

Note that there's absolutely no need to squeeze a 0 or a NULL between the {}. The empty pair of {} will do just fine.

Sign up to request clarification or add additional context in comments.

3 Comments

+1 - Just as an aside, C requires there to be at least one value between the initializer braces. C++ added The empty brace initializer ({ }) specifically because there's no reason that a object's default value has to be anything resembling 0, and the code asking for initialization of an object might have no idea what a sensible default might be (particularly in templates).
I thought int *a = new int[100](); creates a pointer to an array of integers that are zero initialized meaning a[i] would contain 0 and be a dereferenced pointer to the (i+1)th integer in that array rather than a null pointer.
@MatthewD.Scholefield Good spot. I took the liberty of fixing that, since AnT didn't in the intervening year. ;) This shows how the pointer and array syntax inherited from C is confusing in its ugliness, and how much a typedef or two would really help here - or just why not to use new. :P
9

Normally an array will not be initialised by default, but if you initialise one or more elements explicitly then any remaining elements will be automatically initialised to 0. Since 0 and NULL are equivalent you can therefore initialise an array of pointers to NULL like this:

float * foo[42] = { NULL }; // init array of pointers to NULL

4 Comments

Be aware that "int foo1[42] = { 1 };" only inits the first to 1 and the remaining to 0, since by default C++ inits array elements to 0! In your example, you are setting only the first element to 0 and the remaining is set by default to 0.
@amfcosta: I'm not sure why you think the answer is unclear, or why it deserves a down-vote ? The OP was asking about initialising arrays of pointers to NULL.
please see my comment. It is because int foo1[42] = { 0 }; is misleading.
@amfcosta: well I still don't see why it's misleading, but I'll add some clarification if you like.
6

You can switch from array to std::vector and use

std::vector<T*> v(SIZE);

The values will be initialized by NULLs automatically. This is the preferred C++ way.


Update: Since C++11, there is one more way: using

std::array<T*, SIZE> array = {};

This behaves more like a corrected version of C-style array (in particular, avoids dynamic allocations), carries its size around and doesn't decay to a pointer. The size, however, needs to be known at compile time.

9 Comments

Unless the OP does not want a dynamically sized array.
@Billy: Well, the OP could just ignore the possibility for dynamic sizing. C++-style arrays are generally a Good Thing.
If size is known at compile time though, the builtin arrays are better. It's better to avoid dynamic allocation when possible. vectors should be used whenever the size constant is not known at compile time though.
@Billy vectors have many, many advantages over arrays, which have nothing to do with dynamic allocation. For example, vectors carry their size around with them and do not decay into pointers. And one should avoid dynamic allocation - but in one's own code, not in library code.
@Vlad Of course, since C++11 with std::array, we can avoid dynamic allocation while still having all the other benefits of standard containers, including the ability to do bounds-checked indexing (albeit not automatically as your comment might be read to imply) using .at() as in vector
|
2

I am not certain how this is done. I have heard that a pointer is set to NULL by default, though I do not know if this is guaranteed/ in the C++ standard.
It is not guaranteed by the C++ standard. Built in types ( like pointers ) are filled with garbage unless set otherwise.

I am also not sure if initialising through the new operator compared to normal allocation can make a difference too.
What do you mean by "normal allocation" ? If you're talking about an automatic variable, then you can do this:

MyType * pointers[2] = {}

and the pointers should be initialized to NULL.

2 Comments

Pointers are not guaranteed to be initialized to NULL, just like ints are not initialized to 0, in many contexts. Note that your example is equivalent to {NULL, 0} and {} (with the latter being preferred), rather than specifying one value for all of the items in the array.
@RogerPate I know this answer is years late but fixed it now. :)
0
void* p[10] = { 0 };

3 Comments

Be aware that this is only explicitly initialising the first element to 0, the remaining are initialised to zero by default by C++. For example, "int foo1[42] = { 1 };" only inits the first to 1 and the remaining to 0, since by default C++ inits array elements to 0!
More importantly, the compiler initializes the remaining entries to all-bits-zero, which not guaranteed to be the same as the representation for a null pointer.
@kdopen Actually the remaining entries are OK; it's explicitly giving 0 that might be an issue - i.e. you get 0-initialisation if you don't explicitly mention 0. :S "Zero initialization is performed [...] for members of value-initialized class types that have no constructors, including value initialization of elements of aggregates for which no initializers are provided. [...] A zero-initialized pointer is the null pointer value of its type, even if the value of the null pointer is not integral zero." en.cppreference.com/w/cpp/language/zero_initialization Since C++11, use {}.
-1

If you have a member array then there is no way to initialize, unless it's a static member. If the array isn't a static member then you'll have to fill it inside the constructor's body.

That said, chances are you're really better off using a std::vector. Other than for technical reasons such as unavailability of a standard STL for your platform, or the slightly lesser performance a std::vector is better than an array by any and all criteria. If performance is the issue then make sure you profiled and know by numbers that it is an issue.

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.