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

问题描述 投票:0回答:1

我无法理解 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;
c++ c++11 c++14 address-sanitizer
1个回答
0
投票

临时对象会一直保留到创建它们的完整表达式结束为止。完整表达式是不属于另一个表达式的表达式,所以基本上直到下一个

;

这意味着在这个片段中

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
仍然存在,并且包含临时对象中数据的副本。

© www.soinside.com 2019 - 2024. All rights reserved.