-1
#include <vector>


using namespace std;

class NumArray 
{
    public:
        NumArray(vector<int>& nums)
            : nums(nums)
            , length(nums.size())
        {
            vector< vector<int> > tmp(length, vector<int> (length, NULL));
            this->lookup = tmp;
        }

    private:
        vector<int>& nums;
        vector< vector<int> > lookup;
        int length;
};

I got an inefficient way to initialize the vector lookup by constructing vector tmp first, but there should be a method initialize lookup through initializer list explicitly. Like

public:
    NumArray(vector<int>& nums)
        : nums(nums)
        , length(nums.size())
        , lookup(length, vector<int> (length, NULL))
    {

    }

But this doesn't work. Is there any way to fix it?

  • 1
    ***How*** doesn't it work with the initializer list? What problems do you have? – Some programmer dude Mar 07 '21 at 12:48
  • And note that `NULL` is a C backward compatibility macro for null *pointers*, not null values (which doesn't exist in C++). If you want default-constructed or initialized values, don't pass the second argument to the `std::vector` [constructor](https://en.cppreference.com/w/cpp/container/vector/vector). – Some programmer dude Mar 07 '21 at 12:49
  • Also note that a vector size can never be negative, and one should be using `size_t` for storing it. And that the vector you pass for `nums` need to stay alive at least as long as the `NumArray` object you create (otherwise the `nums` reference becomes invalid). – Some programmer dude Mar 07 '21 at 12:51
  • @Someprogrammerdude Thanks for your helpful advice! This error occurs due to the order of initialization. – MangoPomelo Mar 07 '21 at 13:14

1 Answers1

1

What you are doing works fine, you're just not doing it right (emphasis mine):

The order of member initializers in the list is irrelevant: the actual order of initialization is as follows:

  1. If the constructor is for the most-derived class, virtual bases are initialized in the order in which they appear in depth-first left-to-right traversal of the base class declarations (left-to-right refers to the appearance in base-specifier lists)
  2. Then, direct bases are initialized in left-to-right order as they appear in this class's base-specifier list
  3. Then, non-static data member are initialized in order of declaration in the class definition.
  4. Finally, the body of the constructor is executed

This means that in your case:

private:
    vector<int>& nums;
    vector< vector<int> > lookup;
    int length;

lookup is initialized before length, and as such, length may not appear in the lookup constructor.

Swap the declarations of the two to fix the issue, or for a more reliable solution, do not use members in member initializer lists at all. This will work just as well, without potentially causing what you are experiencing right now.

NumArray(vector<int>& nums)
        : nums(nums)
        , length(nums.size())
        , lookup(nums.size(), vector<int> (nums.size(), NULL)) {} // `length` does not need to be used at all
IWonderWhatThisAPIDoes
  • 1,000
  • 1
  • 4
  • 14