Why is the scope of object created using new limited?

Object made using new operator does not seem to be available outside the scope! Isn't that the whole point of the new operator?

https://ideone.com/DDvo9y - Please check this link to see the result.

#include<iostream>

class myClass
{
private:
  int val;
public:
    myClass () = delete;
    myClass (int val):val{val}{}
    int get () const
    {
      return val;
    }
};

bool ifEqualMake (int a, int b, myClass * obj)
{
  if (a == b)      obj = new myClass (a);
  else{
      std::cout << "Difference exists: " << a - b << '\n';
      obj = new myClass (a + b);
    }
  std::cout << " Object made with value :" << obj->get () << '\n';
  return (a == b);
}

int main ()
{
  myClass *obj1 = nullptr;
  myClass *obj2 = nullptr;
  myClass *obj3 = nullptr;

  ifEqualMake (3, 3, obj1);
  ifEqualMake (4, 3, obj2);
  ifEqualMake (4, 4, obj3);

  if(obj1) std::cout << "obj 1 made in heap: " << obj1->get () << '\n';
  if(obj2) std::cout << "obj 2 made in heap: " << obj2->get()<<'\n';
  if(obj3) std::cout << "obj 3 made in heap: " << obj3->get () << '\n';

  delete obj1;
  delete obj2;
  delete obj3;

  return 0;

}

3 answers

  • answered 2019-09-10 02:13 songyuanyao

    The parameter obj is passed by value, that means it's just a copy of the argument, and any modification on itself inside the function (like obj = new myClass (a);) has nothing to do with the original pointer. In the meanwhile, the object constructed inside the function won't be destroyed.

    You might change it to pass-by-reference.

    bool
    ifEqualMake (int a, int b, myClass *& obj)
    //                                  ^
    {
      ...
    }
    

  • answered 2019-09-10 02:18 Lightness Races in Orbit

    It isn't.

    You're confusing the dynamically-allocated object that you created with new, and the pointer that points to it.

    The pointer's scope is limited just like any other automatic-storage-duration object.

    It looks like you meant to use it as an "out" argument to the function ifEqualMake, perhaps by taking a reference to it rather than a copy. Then alterations to it, such as pointing it to a new object, will be mirrored in the calling scope.

  • answered 2019-09-10 02:20 James Picone

    Consider the following function:

    void foo(int i) {
        i = 4;
    }
    
    void bar() {
        int j = 0;
        foo(j);
        std::cout << j << '\n';
    }
    

    You would expect bar to print 0, not 4, because foo is assigning to a local variable.

    This behaviour does not change with pointers. The following code behaves the same way:

    void foo(int* i) {
        int temp = 0;
        i = &temp;
    }
    
    void bar() {
        int* j = nullptr;
        foo(j);
        std::cout << j << '\n';
    }
    

    The simplest fix to the code you present is to take the pointer by reference:

    void foo(int*& i) {
        int temp = 0;
        i = &temp;
    }
    
    void bar() {
        int* j = nullptr;
        foo(j);
        // j now points to a destroyed object
        std::cout << j << '\n';
    }