简体   繁体   中英

How do I initialize dynamic member variable?

I want to store a dynamic array of structs as a member variable within another struct. Is this the proper way to use the constructor given my example in main?

EDIT I corrected some of the obvious mistakes I had in the code (was 6am at the time). I also added another member to B to see if the push_back is still correct. I know my life would be a lot easier using vectors for dynamic memory but I need to do it this way as these are structs to be used with thrust::device_vector in the end.

struct A
{
    float mem1;
    int mem2;
};
struct B
{
    A * Aarr1;
    A * Aarr2;
    B(A * a1, A * a2): Aarr1(a1), Aarr2(a2){}
};
int main()
{
    A * test = new A[5];
    A * test2 = new A[10];
    vector<B> btest;
    btest.push_back(B(test, test2));
    for(int i=0; i<5; i++)
        printf("mem1: %f, mem2: %i \n", btest[0].Aarr[i].mem1, btest[0].Aarr[i].mem2);
}

Taken in isolation, the constructor is fine. However, there are many other problems with the code.

As it stands, your code is leaking memory since the array is never deallocated.

You might want to consider moving away from using C arrays to std::vector or std::array .

There's also a bug in printf() (misspelt as print() ): one of the two mem1 should be mem2 .

The constructor of B is OK, but the way you invoke push_back() is not:

btest.push_back(B(A));

You should do this:

btest.push_back(B(test));

Moreover, the explicit construction of a B object is not necessary, since your constructor is not marked as explicit :

btest.push_back(test);

Also consider using automatic memory management rather than raw pointers ( std::vector<> instead of arrays, smart pointers instead of pointers). This way, you will avoid leaking memory due to forgetting this:

delete test;

Leaking aside, the worst thing is that your code also has Undefined Behavior, because it uses the value of uninitialized variables (the member variables of A within the for loop).

Finally, you shouldn't use : after class names in a class definition. This is how you could rewrite your code in C++11:

#include <vector>
#include <cstdio>

struct A // Do not use ":" here, that's for introducing inheritance,
         // which you are not using in your example.
{
    float mem1 = 0.0; // In C++11, you can specify default initialization
    int mem2 = 0;     // for your member variables this way. In C++03 you
                      // would have to define a default constructor which
                      // initializes your member variables to the desired
                      // value.
};

struct B
{
    std::vector<A> Aarr;
//  ^^^^^^^^^^^^^^
//  Prefer using standard containers over dynamically allocated arrays, as
//  it saves your from taking care of memory management and avoids leaks.

    explicit B(size_t s): Aarr(s) { }
//  ^^^^^^^^
//  It is usually a good idea to mark constructors which take on argument
//  and are not copy constructors as explicit, to avoid awkward implicit
//  conversions.
};
int main()
{
    std::vector<B> btest;
    btest.push_back(B(5));
//                  ^^^^
//                  We need to explicitly construct an object of type B,
//                  because we have marked B's constructor as explicit.

    for(int i=0; i<5; i++)
    {
        std::printf(
             "mem1: %f, mem2: %i \n", 
            btest[0].Aarr[i].mem1, 
            btest[0].Aarr[i].mem2
            //                  ^
            //                  You had "mem1" here.
            );
    }
}

There are few minor mistakes and typos in your code. It should look like this:

struct A  // <-- no ':' after name type
{
    float mem1;
    int mem2;
};

struct B  // <-- no ':' after name type
{
    A * Aarr;
    B(A * a): Aarr(a){}
};

int main()
{
    A * test = new A[5];
    vector<B> btest;
    btest.push_back(B(test)); // <-- test, A is name of type
    for(int i=0; i<5; i++)
        printf("mem1: %f, mem2: %i \n", // <-- printf, not print
                btest[0].Aarr[i].mem1, btest[0].Aarr[i].mem1);
}

Also consider using std::vector or std::array instead of C-style arrays as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM