6

When using STL containers, I am not sure whether an int allocated by the default allocator has been zeroized. The following code indicates 'yes' to the question:

#include <map>
#include <iostream>

int main() {
  using namespace std;
  map<int, int> m;
  cout << m[1234] << endl;
}

Since no document has confirmed this, I don't dare to take it for granted.

LihO
  • 41,190
  • 11
  • 99
  • 167
peter
  • 1,034
  • 1
  • 9
  • 23
  • 1
    The allocator will default-construct. This should be relevent: – RobH Mar 06 '12 at 13:39
  • Or, from MSDN: < http://goo.gl/5qvQb > – RobH Mar 06 '12 at 13:41
  • 1
    The proper term is "default initialized"; e.g. `map` will default the strings to `""` – MSalters Mar 06 '12 at 13:44
  • @RobH: In STL containers, "allocator" generally means `std::allocator<>` or its replacement. – MSalters Mar 06 '12 at 13:45
  • @LuchianGrigore should work now. – RobH Mar 06 '12 at 13:46
  • @MSalters To be more long-winded if you wish, accessing the map in the way shown will cause a new value to be created using the (in this case default) allocator, which calls `new`, which will default-construct the newly-created items. – RobH Mar 06 '12 at 13:52
  • @RobH: That's quite unlikely: `std::allocator::allocate` only allcoates memory, it doesn't call `new T`. To construct a `T` in that memory, you can then use `std::allocator::construct(ptr, 1)`. That doesn't call `new T` either, since the memory is already allocated. TL;DR: `new T` does in one step what `std::allocator` does in two steps. – MSalters Mar 06 '12 at 13:59
  • @MSalters I stand corrected. I thought that the allocator was used to allocate memory for new values, but it appears only to be used (in the MSVC implementation) by map's underlying tree. I also notice while I'm in there the source of Luchian's code snippet. – RobH Mar 06 '12 at 14:32

4 Answers4

6

You'll see, inside the implementation of std::map::operator[], if the element is not found at the index, a new one is inserted and returned:

ReturnValue = this->insert(where, make_pair(key_value, mapped_type()));

where mapped_type is the second type, in your case int. So yes, it is default-initialized to 0, since it's inserted as mapped_type().

MSalters
  • 173,980
  • 10
  • 155
  • 350
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • I know that an int will be inserted, but I'm not sure whether it's zeroized. I'm not sure whether `new int` would return a pointer to 0. – peter Mar 06 '12 at 13:44
  • @peter it's not `new int`, it's `int()`, which will yield `0`. – Luchian Grigore Mar 06 '12 at 13:45
  • @peter: That's another question (no; use `new int()` for that). `std::map` doesn't allocate indiviudal `int` objects, but nodes which each hold a `pair` – MSalters Mar 06 '12 at 13:47
  • 2
    actually `new int` is bound to yield a pointer to an unpredictable value; `new int()` will yield a pointer to zero as `int()` is an `int` initialized to zero. – Dietmar Kühl Mar 06 '12 at 13:49
6

The standard guarantees that objects created as a result of using the subscript operator are default constructed. Whether the default constructor for any particular class zeroes the members you expect to be zeroed is up to theclass. For classes without constructors members are default constructed and default construction fundamental types amounts to setting the to their version of "zero".

Note, this has nothing to do with allocators! ... and it is pretty safe to assume that tbe allocators leave the memory untouched, except possibly dedicated debugging allocators (or allocators written by people tricked into thinking that zeroing the memory might be Good Thing rather than a device hiding bugs). ... and the debugging allocator wouldn't zero the memory but fill it with a recognizable pattern ( e.g. resulting in 0xdeadbeef when viewed in hexadecimal).

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
2

Maybe this: 8.5.5 Initializers C++ Standard - ANSI ISO IEC 14882 2003

To zero-initialize an object of type T means: if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;

bartolo-otrit
  • 2,396
  • 3
  • 32
  • 50
1

It seems that the default allocator template will use new int() to default-ininitialize an int to 0, according to C++ ISO standard 14882:2003. Chapter 8.5, Clause-5,7:

To zero-initialize an object of type T means:

  • if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;

To value-initialize an object of type T means:

  • if T is a class type (clause 9) with a user-declared 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 non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;

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

  • otherwise, the object is zero-initialized

To default-initialize an object of type T means:

  • if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

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

  • otherwise, the object is zero-initialized.

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

There are also similar rules in C++11 ISO Standard draft.

V.D.D
  • 135
  • 1
  • 7