new keyword

Fred* p = new Fred();
Fred* p = new Fred[];

what's the difference between these two statement ;
closed account (o1vk4iN6)
new Fred[]; shouldn't compile, it requires a parameter to determine the size of the array of objects to allocate.

new Fed[10];
closed account (jwkNwA7f)
Fred* p = new Fred(); This allocates an object.
Fred* p = new Fred[]; This allocates an array of objects, as mentioned by xerzi. Like xerzi said, it should have the number of objects between the brackets.

EDIT: Wow, my 500th post!
Last edited on
As well as

1
2
Fred* p = new Fred();
Fred* p = new Fred[42]; // now with the required size (which can be 0) 


you're got these, too

1
2
Fred* p = new Fred;
Fred* p = new Fred[42]();


and if your compiler understands C++11, the curly braces {} forms as well

1
2
Fred* p = new Fred{};
Fred* p = new Fred[42]{};


Andy
Last edited on
Fred* p = new Fred[42]();


Does that work? I didn't think you could invoke constructors when using new[]... it just always uses the default ctor.
closed account (Dy7SLyTq)
nope disch is right.
http://ideone.com/ZKo5S8
Works for me, with GCC and MSVC

But the () isn't constructor invocation. It's value initialization.

If you provide an explicit default constructor, that will be used and the initialization does nothing. But if you don't provide an explicit constructor, you get:

without ()s

  -842150451

  -842150451
  -842150451
  -842150451
  -842150451

with ()s

  0

  0
  0
  0
  0


(the "rubbish" in the memory is regular here as it's a MSVC debug build, and the debug version of the CRT library fills newly allocated memory with the fixed pattern: 0xCDCDCDCD)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
using namespace std;

#define NO_EXPLICIT_CONSTRUCTOR

class Fred
{
public:
#ifdef NO_EXPLICIT_CONSTRUCTOR
  // no constructor
#else
  Fred() : ballChange(1)
  {
    // "forgot" to init step
  }
#endif
  int step;
  int ballChange;
};

int main()
{
  int count = 4;

  Fred* p1  = new Fred;
  Fred* pa1 = new Fred[count];

  Fred* p2  = new Fred();
  Fred* pa2 = new Fred[count]();

  cout << "without ()s" << endl;
  cout << endl;

  cout << "  " << p1->step << endl;
  cout << endl;
  for(int i = 0; count > i; ++i)
    cout << "  " << pa1[i].ballChange << endl;
  cout << endl;

  cout << "with ()s" << endl;
  cout << endl;

  cout << "  " << p2->step << endl;
  cout << endl;
  for(int i = 0; count > i; ++i)
    cout << "  " << pa2[i].ballChange << endl;
  cout << endl;

  delete    p1;
  delete [] pa1;

  delete    p2;
  delete [] pa2;

  return 0;
}



Andy

value initialization
http://en.cppreference.com/w/cpp/language/value_initialization
(the example code here includes the array case.)

With the faulty, explicit constructor the output is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
without ()s

  -842150451, 1

  -842150451, 1
  -842150451, 1
  -842150451, 1
  -842150451, 1

with ()s

  -842150451, 1

  -842150451, 1
  -842150451, 1
  -842150451, 1
  -842150451, 1
Last edited on
Uniform initialization is supported when an object is created with a new expression.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <memory>

struct Fred
{
  int step;
  int ballChange;
};

std::ostream& operator<< ( std::ostream& stm, const Fred& f )
{ return stm << "Fred{" << f.step << ',' << f.ballChange << '}' ; }

int main()
{
    constexpr int N = 5 ;

    {
        // value initialization
        std::unique_ptr< Fred[] > p( new Fred[N] () ) ;
        for( int i = 0 ; i < N ; ++i ) std::cout << p[i] << ' ' ;
        std::cout << '\n' ;
    }

    {
        // aggregate initialization
        std::unique_ptr< Fred[] > p( new Fred[N] { {0,1}, {2,3}, {4,5} } ) ;
        for( int i = 0 ; i < N ; ++i ) std::cout << p[i] << ' ' ;
        std::cout << '\n' ;
    }

    // etc.
}

http://ideone.com/URvmbm
Last edited on
Topic archived. No new replies allowed.