Static member that contains unique_ptr

Hello everyone,
I wrote the following code to regenerate the problem I met:
I'm trying to have a static member ("accommodation") that contains unique_ptr. When I define accommodation in the first object "human1" it looks ok, but when i want to get it in the second object "human2" I got an error.
Why is it like that? Shouldn't the ownership of "unique_ptr<int[]> address_idx" always stay in the static member?

Thanks in advance
Best,
Chuuuing

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
57
58
59
60
61
62
63
  #include <iostream>
#include <memory>
using namespace std;

struct Accommodation {
    unique_ptr<int[]> address_idx;
    int count;

    Accommodation(unique_ptr<int[]> address_idx, int count) : address_idx(move(address_idx)), count(count) {
    }

};
class Human {
    static std::string planet;
    static Accommodation* accommodation;

    int age;
    double height;
    double weight;

public:
    Human(int age):age(age) {
    }
    void walk() {
        planet = "saturn";
    }
    void changeAddress() {
        auto address_idx = unique_ptr<int[]>(new int[5]);  //ALTERNATIVE 1
        address_idx[0] = 0;
        address_idx[1] = 1;
        address_idx[2] = 2;
        address_idx[3] = 3;
        address_idx[4] = 4;

        Accommodation ac = Accommodation(move(address_idx),5);
        accommodation = &ac;
    }

    std::string getPlanet() {
        return planet;
    }

    int getAccomodationCount() {
        return accommodation->count;
    }
};

std::string Human::planet;  //static variable need to declare extra with its class
Accommodation* Human::accommodation;

int main() {
    std::cout << "Hello, World!" << std::endl;
    Human human1(20);
    human1.walk();
    human1.changeAddress();

    Human human2(15);
    std::cout<< "human2's planet = " <<human2.getPlanet();
    std::cout<< "human2's accommodation = " <<human2.getAccomodationCount();

    return 0;
}
Last edited on
Human::accomodation is set to point to a temporary in Human::changeAddress(). When you use it in human2.getAccomodationCount(), it's invalid, your program isn't deterministic.
Last edited on
hi kbw, thanks for replying.
is there a way to fix this problem? I thought as a static member, once it's assigned, it won't change.
The problem isn't that accommodation changes its value - it doesn't. The problem is that that the value you assign to it is worthless in the first place, because it's pointing to a local object ac that is destroyed when it goes out of scope.

You need to make it point to something that persists after the changeAddress() method exits, i.e. to something that isn't an object with local scope.

Perhaps dynamically allocate the Accommodation object on the heap, rather than creating a local variable for it?
It's not entirely clear on what you're trying to do. However, I'll just fix what I see.
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
#include <iostream>
#include <memory>
#include <string>
#include <vector>

struct Accomodation {
    std::vector<int> address_idx;

    Accomodation(std::vector<int> source) : address_idx(std::move(source)) {
    }
    size_t size() const {
        return address_idx.size();
    }
};

class Human {
    inline static std::string planet;
    inline static std::unique_ptr<Accomodation> accomodation;

    int age;
    double height;
    double weight;

public:
    Human(int age) : age(age) {
    }
    void walk() {
        planet = "saturn";
    }
    void changeAddress() {
        std::vector<int> address_idx(5);
        for (size_t i = 0; i != address_idx.size(); ++i)
            address_idx[i] = i;

        accomodation = std::make_unique<Accomodation>(std::move(address_idx));
    }
    std::string getPlanet() const {
        return planet;
    }
    int getAccomodationCount() const {
        return accomodation ? accomodation->size() : -1;
    }
};

int main() {
    Human human1(20);
    human1.walk();
    human1.changeAddress();

    Human human2(15);
    std::cout<< "human2's planet = " << human2.getPlanet() << '\n';
    std::cout<< "human2's accommodation = " << human2.getAccomodationCount() << '\n';
}
Last edited on
Topic archived. No new replies allowed.