2

In C, we actually do

struct node *p = (node*)malloc(sizeof(node));   // casting is not necessary
p->a = 0;      // first  element
p->b = NULL;   // second element

to dynamically allocate spaces in the memory, but how can I do this in C++ way?

Is the line below a correct guess?

node *p = new node {0, NULL};
Kevin Dong
  • 4,211
  • 5
  • 21
  • 52
  • 1
    This is going to get a lot of personal opinion. I personally find the C way best even in C++ code. – Eugene K Mar 27 '15 at 15:55
  • 5
    @EugeneK: Personal opinion doesn't really come into it. For the vast majority of C++ types, your "C way" is _wrong_. I don't just mean ill-advised, or bad style. I mean _wrong_. Broken. – Lightness Races in Orbit Mar 27 '15 at 16:01
  • unless you are implementing some low level library, never type new – sp2danny Mar 27 '15 at 16:03
  • @LightnessRacesinOrbit I didn't mean to extrapolate that the same pattern can be followed for every memory allocation. It's more so that initializer lists, and the use of 'new' is up for discussion. – Eugene K Mar 27 '15 at 16:06
  • 2
    @EugeneK Instead of sometimes using malloc and sometimes using new, and having to remember whether to free or delete, why not just always use new (if manual allocation has to be used), so there is one less thing to go wrong? – Neil Kirk Mar 27 '15 at 16:07
  • @Neil Or never use either, so there are _no_ things to go wrong. – Lightness Races in Orbit Mar 27 '15 at 16:12

2 Answers2

6

Yes, you are correct.

Assuming node is an aggregate, your C++ version is right (modulo NULL rather than nullptr).

That being said, if these initial values are "defaults", you would conventionally write a default constructor to initialise those members for you automatically:

struct node
{
    int a;
    node* b;

    node() : a(0), b(nullptr) {}
};

Then you'd just write:

node* p = new node;

Or, better:

auto p = std::make_unique<node>();

Or, better yet:

node n;

Default-construction has some consequences though. You may not want any constructors.

Lightness Races in Orbit
  • 358,771
  • 68
  • 593
  • 989
1

In C++ you would avoid a naked new and either create a shared/unique pointer with std::make_shared/std::make_unique in C++11/14 or encapsulate the allocation in a handle-class following the RAII idiom.

To give an example of how that would work:

class Foo {
    const int i;
    public:
    int j;
    Foo(int i) : i{i}, j{0} {}//constructor
    void foo() {std::cout << i << "\n";}
};

int main() {
    unique_ptr<Foo> fp = make_unique<Foo>(5);
    fp->foo();
    return 0;
}

In case the constructor looks a bit confusing to you, a short explanation: The colon after the constructors signature starts the initialization declaration. In this section you have to initialize const-values, but you can initialize all values there. Thus constructors, which take arguments often look like this:

Foo(ArgType1 arg1, ArgType2 arg2,...,ArgTypeN argN) : 
   member1(arg1), member2(arg2), ... , memberN(argN) {//empty body}

Be sure to pay attention to the rule of three/five, when writing constructors.

Community
  • 1
  • 1
midor
  • 4,936
  • 1
  • 18
  • 48
  • The `new` part of it is a separate issue, I think. To me, it seems like the question is more about *initialization* of the structure's data. – crashmstr Mar 27 '15 at 16:02