Mesut Çiftçi
Mesut Çiftçi

Reputation: 160

Why vectors inside two struct have the same address?

For avoid duplicate code, i want to build this generic structure. I want the numbers24 vector inside the scaledown24 struct to be different from the numbers32 vector inside the scaledown32 struct. So when I make a change, they won't be able to influence each other. But when I run the program, the printAddress function shows that the address of the two vectors is the same. How can i fix this. Thanks.

#include <iostream>
#include <vector>

struct ScaleDown24{
    static std::vector<int> getVector() {
        std::vector<int> numbers24(3);
        return numbers24;
    };
    static inline void printAddress(std::vector<int>sumNumbers ) {
        std::vector<int> *p = &sumNumbers;
        std::cout << p << "\n";
    }
};

struct ScaleDown32{
    static std::vector<int> getVector() {
        std::vector<int> numbers32(4);
        return numbers32;
    };
    static inline void printAddress(std::vector<int>sumNumbers ) {
        std::vector<int> *p = &sumNumbers;
        std::cout << p << "\n";
    }
};

template<typename ScaleFunction>
void scaleDown(){
    std::vector<int>sumNumbers = ScaleFunction::getVector();
    ScaleFunction::printAddress(sumNumbers);

}

int main()
{
    scaleDown<ScaleDown24>();
    scaleDown<ScaleDown32>();
    return 0;
}

Upvotes: 0

Views: 97

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 596948

There are several problems with your code. Mainly stemming from the fact that both getVector() methods return their vectors by value, and both printAddress() methods take their arguments by value as well. So you are dealing with copies of vectors all over the place. You are seeing memory getting reused in different contexts.

You need to introduce some references into your code to avoid those copies, eg:

#include <iostream>
#include <vector>

struct ScaleDown24{
    static std::vector<int>& getVector() { // <-- return a reference
        static std::vector<int> numbers24(3); // <-- make static to avoid returning a reference to a local variable
        return numbers24;
    };
    static inline void printAddress(const std::vector<int> &sumNumbers ) { // <-- take a const reference
        const std::vector<int> *p = &sumNumbers;
        std::cout << p << "\n";
    }
};

struct ScaleDown32{
    static std::vector<int>& getVector() { // <-- return a reference
        static std::vector<int> numbers32(4); // <-- make static to avoid returning a reference to a local variable
        return numbers32;
    };
    static inline void printAddress(const std::vector<int> &sumNumbers) { // <-- take a const reference
        const std::vector<int> *p = &sumNumbers;
        std::cout << p << "\n";
    }
};

template<typename ScaleFunction>
void scaleDown(){
    std::vector<int> &sumNumbers = ScaleFunction::getVector(); // <-- save a reference, not a local copy
    ScaleFunction::printAddress(sumNumbers); // <-- prints the original vector that is inside getVector()!
}

int main()
{
    scaleDown<ScaleDown24>();
    scaleDown<ScaleDown32>();
    return 0;
}

Live Demo

Upvotes: 2

NathanOliver
NathanOliver

Reputation: 180825

Your printAddress() function takes its argument by value. That means you are making a copy of any vector that you pass to it, and it is that copy that you are printing the address of.

What you need to do is pass the vector argument by reference instead, so that you can get the address of the original, not a copy. That would look like this:

static inline void printAddress(std::vector<int>& sumNumbers )
//                         this means reference ^       

You are also going to have an issue with scaleDown():

template<typename ScaleFunction>
void scaleDown(){
    std::vector<int>sumNumbers = ScaleFunction::getVector();
    ScaleFunction::printAddress(sumNumbers);

}

because sumNumbers is a non-static local variable so it can have the same address each time you call that function. If you just want each ScaleFunction to have its own vector, you can make it `static to do that like this:

template<typename ScaleFunction>
void scaleDown(){
    static std::vector<int>sumNumbers = ScaleFunction::getVector();
    ScaleFunction::printAddress(sumNumbers);

}

Also note that since printAddress() doesn't modify the vector, and you don't want it to, you can make the vector const to help enforce that. That would give you this:

static inline void printAddress(const std::vector<int>& sumNumbers ) {
    // no need for the pointer here
    std::cout << &sumNumbers << "\n";
}

Upvotes: 3

Related Questions