c++ 为什么ASAN没有将其报告为stack-use-after-scope问题?

oyt4ldly  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(89)

我无法理解Address Sanitizer -(stack-use-after-scope)背后的概念。

#include <iostream>
using namespace std;
class User {
        public:
        User(){
                _name = "No Name";
        }
        User(string name){
                _name = name;
                _salary = 0;
        }

        string getName(){
                return _name;
        }

        int* getRoles(){
                return _roles;
        }
        private:
        string _name;
        int _salary;
        int _roles[5];
};

class Employee {
        public:
        Employee(User user){
                _user = user;
        }

        User getUser(){
                return _user;
        }
        private:
        User _user;

};
int main() {
        // your code goes here

        User user("User1");
        Employee employee(user);

        auto roles = employee.getUser().getRoles();
        roles[0] = 1;
}

字符串
这里我理解getUser返回一个可能被销毁的临时对象,而roles变量可能指向一个已经被回收的位置,这样理解正确吗?
类似地,下面的代码给出错误。

string name = "name123";
auto arr = name.substr(0,4).c_str();
cout<<arr[0];


但为什么不是这样呢?

string name = "name123";
string sub(name.substr(0,4).c_str());
cout<<sub;

baubqpgj

baubqpgj1#

临时对象会持续到创建它们的完整表达式的末尾。完整表达式是一个不属于另一个表达式的表达式,所以基本上直到下一个;
这意味着在这个片段中,

auto arr = name.substr(0,4).c_str();
cout<<arr[0];

字符串
arr是指向substr返回的临时对象所拥有的数组的指针。由于该对象在创建它的完整表达式的末尾被销毁,因此当您试图在下一条语句中读取它时,它不再存在。
本声明中

string sub(name.substr(0,4).c_str());
cout<<sub;


c_str返回的指针指向的数组继续存在,直到完整表达式结束。这意味着当sub的构造函数访问它以复制其内容时,它仍然是活动的。
cout语句运行时,临时字符串已经被销毁,但这不再重要,因为sub仍然存在,并且包含来自临时对象的数据副本。

相关问题