2

I looked some code it says one of the reason to use "new" is to make a pointer not being destroyed after a function. For example

void input(string name, int age)
{
  student *st = new student(name,age);
  st->change();
}
int main(){
  input("guagua",25);
  if(!st){ cout<<"there is a pointer"<<endl;}
  delete st;
  return 0;
}

I have a simple class student whose head file looks like this, where change funtion just cout a sentence.

class student{

  public:
    student(string na, int ag);
    void change();
  private:
    string name;
    int age;
};

If new allocate a memory then I should be able to see "there is a pointer". However, this program cannot be compiled and the error is

    ‘st’ was not declared in this scope

How could I make st be visible after input function?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • That's not very good code. Don't know where you got it from, but you should read [a good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) instead. – Lightness Races in Orbit May 05 '18 at 18:04
  • What you have read is correct, but your code declares the pointer in the local scope of the function `input`, hence the error message that it is not visible in the scope of `main`. You could move it out of the `main` function so that it becomes global. – RWRkeSBZ May 05 '18 at 18:36
  • 1
    "global scope" and "heap allocation" are two completely different and unrelated topics. Your question deals with the later. – Code-Apprentice May 05 '18 at 18:59
  • Please don't put the answer into the question. Just accept the best one, optionally writing it yourself first. – Deduplicator May 05 '18 at 21:20

1 Answers1

2

In this example the object has been created and still exists in memory, but you don't have a pointer to it anymore.

The reason is that st goes out of scope in input and so the value of the pointer (where the objects is) is lost.

The st in the main function has not been declared in that scope and so it doesn't exist there.

So in this example you would need to return the pointer with something like:

student* input(string name, int age)
{
  student *st = new student(name,age);
  st->change();
  return st;
}

then you can use it:

int main(){
  auto st = input("guagua",25);
  if(!st){ cout<<"there is a pointer"<<endl;}
  delete st;
  return 0;
}

Another option could be to use a global variable for st, or to use a smart pointer.

std::shared_ptr in general could be a drop-in replacement for a raw pointer, but you should prefer the use of a std::unique_ptr if you don't need shared ownership.

Here is an example:

std::unique_ptr<student> input(string name, int age)
{
    auto st = std::make_unique<student>(name, age);
    st->change();
    return st;
}

int main(){
    auto st = input("guagua", 25);
    if(!st){ cout << "there is a pointer" << endl; }
    return 0;
}
wally
  • 10,717
  • 5
  • 39
  • 72
  • Why would `std::shared_ptr` be best? – Benjamin Lindley May 05 '18 at 18:31
  • 1
    @BenjaminLindley because then there is no need to remember to `delete`. Did I miss something? – wally May 05 '18 at 18:35
  • That's a reason to use a smart pointer. But why a shared pointer specifically? – Benjamin Lindley May 05 '18 at 18:36
  • @BenjaminLindley Because it is practically a drop-in replacement for a raw pointer. I am curious what else you have in mind? – wally May 05 '18 at 18:45
  • 1
    I don't mind suggesting the use of `std::shared_ptr`. I only take issue with suggesting it is the best option without a demonstration that shared ownership is required. And the alternative is `std::unique_ptr`, which should be the default if no such demonstration has been made. – Benjamin Lindley May 05 '18 at 18:58
  • @BenjaminLindley Fair enough. Best is a strong word. – wally May 05 '18 at 19:16