Home > Net >  Store memory address of local variable in global container
Store memory address of local variable in global container

Time:09-23

In my understanding it is not possible to store the address of a local memory in a global container, because the local variable will eventually be destroyed.

class AA {
  std::string name;
public:
  explicit AA(std::string n) : name(n) {}
  std::string getName() const {
    return name;
  }
};

class Y {
  std::vector<std::reference_wrapper<AA>> x;
public:
  void addAA(AA& aa) {
    x.emplace_back(aa);
  }
  AA& getLastA() {
    return x.back();
  }
};

void foobar(Y& y) {
  AA aa("aa");
  y.addAA(aa);
}

int main() {

  Y y;
  foobar(y);
  std::cout << y.getLastA().getName() << std::endl; // error - probably because the local aa has been destroyed.
  return 0;
}

However, I do not understand why this code works:

void foobar(Y& y, AA& aa) {
  y.addAA(aa);
}

int main() {

  Y y;
  {
    AA aa("aa");
    foobar(y,aa);
  }


  std::cout << y.getLastA().getName() << std::endl;
  return 0;
}

aa is again created in another scope and should be destroyed. However, it is possible to get its name later in main. The code works fine.

Why don't we get an error in the second case?

CodePudding user response:

Rust has a borrow checker that permeates the language and is its defining characteristic. In Rust, such code would be forbidden.

C is a language with a long history and the reason why there's no error diagnostics for this, I assume, is because when the language was created it was not a concern. At those times the C philosophy was mainstream: "the programmer knows everything". So, it would follow that the programmer knows that they violated lifetime safety, and therefore the error message is redundant.

Now, the C committee is preoccupied with making sure that the versions of C are as much backwards-compatible as possible, and enforcing the provided snippet to fail may break existing code. Thus, it is not in the near future for lifetime violations to be in the standard any time soon.

What committee seems to slide towards regarding this kind of question is that if you want to enforce something that's not covered by the standard, you should use third-party static analysis tools. There are few of them, though, most notable is clang-tidy, but none of them, as far as I know, support rigorous lifetime analysis to detect the errors demonstrated by your snippet.

CodePudding user response:

In my understanding it is not possible to store the address of a local memory in a global container, because the local variable will eventually be destroyed.

You're starting from a flawed understanding. It's certainly a bad idea to keep the address of a local variable beyond its lifetime, but it's still possible. As you say, it's a bad idea because that pointer will quickly become invalid. Even so, you can take the address of any variable, and the language won't prevent you from storing it wherever you like. Like C before it, C lets you do a great many things that are bad ideas, so be careful.

  •  Tags:  
  • c
  • Related