0

In my code, I have a std::map that looks something like this:

std::map<std::string, A*> myMap;

where A is one of my custom classes.

When I access a map element which does not exist via operator[] like so:

std::string s("hello");
A* pA = myMap[s];

I know that a new element will be created with that key but I would like the pointer to be initialized to NULL. In other words, if myMap[s] exists, a valid pointer should be returned. If not, I would like pA to be NULL after the above code executes.

By default, will pA contain garbage if myMap[s] doesn't exit? How can I make it so that pA contains the value NULL if the element doesn't exit?

user974967
  • 2,928
  • 10
  • 28
  • 45
  • 1
    It will be a nullptr if the key was not present before your invoke. The map-value of such a resulting auto-insertion, in your case a pointer type, is value-initialized, and a value-intialized pointer per the standard is zero-initialized, which is synonymous to a nullptr. Ie. you get it for free. – WhozCraig Feb 26 '13 at 03:23
  • Would the downvoter care to elaborate? I explained exactly what I was trying to achieve and asked a question about the default behavior in provided situation. – user974967 Feb 26 '13 at 03:23
  • @user974967 The question shows no research effort (i.e. you didn't even try to read the manual). – melpomene Feb 26 '13 at 03:25
  • @melpomene manual? what manual is that? You mean the standard? – WhozCraig Feb 26 '13 at 03:27

2 Answers2

3

Short Answer: Yes, your pointer can reliably be considered a nullptr on a new key lookup with no prior value.

Long Answer:

Per the standard:

C++11 § 23.4.4.3,p5

T& operator[](key_type&& x);

Effects: If there is no key equivalent to x in the map, inserts value_type(std::move(x), T()) into the map.

Note particularly the use of T(), where T in this case is your pointer type. This leads to...

C++11 § 8.5,p10

An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

By the definition of value initialization:

C++11 § 8.5,p7

To value-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

  • if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.

  • if T is an array type, then each element is value-initialized;

  • otherwise, the object is zero-initialized.

Which brings us to what it means for your object-type to be zero-initialized:

C++11 § 8.5,p5

To zero-initialize an object or reference of type T means:

  • if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression, converted to T (103)

  • if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;

  • if T is a (possibly cv-qualified) union type, the object’s first non-static named data member is zero- initialized and padding is initialized to zero bits;

  • if T is an array type, each element is zero-initialized;

  • if T is a reference type, no initialization is performed.

103) As specified in 4.10, converting an integral constant expression whose value is 0 to a pointer type results in a null pointer value.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
2

Yes new elements in map for embedded types like int or pointer are zero-initialized, so your pointer will be NULL.

Slava
  • 43,454
  • 1
  • 47
  • 90