1

Hi I am unable to use a vector in the constructor. I'm trying to parse a vector that contains [x,y] coordinates into the object.

The errors I've gotten are runtime error and bad alloc.

Is there something I'm missing?

Do I have to use dynamic memory allocation?

ShapeTwoD(Parent Class of Child Class Square):

class ShapeTwoD {

protected:
  string name;
  bool containsWarpSpace;
  vector<string> vect;

private:
public:
  ShapeTwoD() {}

  ShapeTwoD(string name, bool containsWarpSpace, vector<string> vect) {
    this->vect = vect;
    this->name = name;
    this->containsWarpSpace = containsWarpSpace;
  }

Class Square that is a child of ShapeTwoD:

class Square : public ShapeTwoD {

public:
  Square() : ShapeTwoD(name, containsWarpSpace, vect) {
    this->vect = vect;
    this->name = name;
    this->containsWarpSpace = containsWarpSpace;
  }

  ~Square() {}
};

Main Function:

  vector<string> temp;

  string merge;

  for (int i = 0; i < 4; i++) {
    cout << "Please enter x-ordinate of pt " << i + 1 << " :";
    cin >> x;
    cout << "Please enter y-ordinate of pt " << i + 1 << " :";
    cin >> y;

    merge = x + ", " + y;

    temp.push_back(merge);
  }
  Square obj;

  obj.setName(shape);
  obj.setCoord(temp);

  if (specialtype == "ws") {
    obj.setContainsWarpSpace(true);
  }

  else if (specialtype == "ns") {
    obj.setContainsWarpSpace(false);
  }

  myvector.push_back(obj);
  temp.clear();

  cout << "\nRecords successfully stored. Going back to main menu ...\n"
       << endl;
}

enter image description here

4
  • 3
    Please post a minimal, reproducible example. This includes the error message Commented Aug 6, 2020 at 7:13
  • 1
    Where do you think name,containsWarpSpace,vect come from in the Square constructor? Commented Aug 6, 2020 at 7:15
  • It is inherited from the parent class? Commented Aug 6, 2020 at 7:17
  • What is x and y? Note that is they are integers, this: merge = x + ", " + y; is very wrong. Live demo: godbolt.org/z/arePj4. Commented Aug 6, 2020 at 7:47

2 Answers 2

1

In your Square constructor, you are not passing any arguments:

Square() : ShapeTwoD(name,containsWarpSpace,vect){
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^

That means that the name, containsWarpSpace and vect refer to the parent class fields, which haven't been initialized yet (because that's the job of the ShapeTwoD constructor). So you are taking uninitialized variables and passing them into the constructor to initialize those same variables. More explicitly what you are doing is

Square():ShapeTwoD(this->ShapeTwoD::name, 
    this->ShapeTwoD::containsWarpSpace, this->ShapeTwoD::vect){

You should either pass them in:

Square(string name, bool containsWarpSpace, vector<string> vect)
    :ShapeTwoD(name,containsWarpSpace,vect) {

or pass a sensible default:

Square() : ShapeTwoD("", false, {}) {
Sign up to request clarification or add additional context in comments.

2 Comments

iirc - but I'm not a language lawyer - but if So you are taking uninitialized variables and passing them into the constructor to initialize those same variables would be really done (if the constructor fo ShapeTwoD would be ShapeTwoD(const std::string &name, const bool &containsWarpSpace, const std::vector<std::string> &vect) then it would not be a problem. The problem is imho, that a copy is created. But I don't know that for sure so this claim might be wrong.
I'm not a language lawyer either, but given OP's response to a comment ("Where do you think name,containsWarpSpace,vect come from in the Square constructor? -- It is inherited from the parent class?") I assume they were looking for a 'entry level' explanation of which the main point is "You shouldn't pass the base class field into the base class constructor". I'm open to suggestions of making the answer more correct yet not less clear.
0

The problem is:

merge = x + ", " + y;

The ", " is a const char[3] (a null terminated character array). As an array, it decays to a pointer (const char *), which is offset by x+y as a result of summation with int. The resultant pointer refers to an unknown memory location. Next null byte is not guaranteed to reside in accessible address range; even if such byte is in an accessible address, the output would not be meaningful; because you are triggering UB. You can fix it like this:

merge = std::to_string(x) + ", " + std::to_string(y);

Regards, FM.

2 Comments

The question does not show of what type x and y are.
Right. I deduced it from cout.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.