范围后的堆栈使用:有效报告还是误报?
stack use after scope: a valid report, or a false positive?
我在我们的代码库 (g++ -fsanitize=address
) 中发现了一个作用域后堆栈使用错误,我想知道这是否是一个有效的问题,我应该去修复每次出现的问题这样的模式,还是地址消毒器的误报?
最小和简化的例子如下:
#include <string>
#include <stdio.h>
struct MyStr
{
MyStr() = default;
MyStr(const char *s) : text(s) {};
MyStr substr(size_t length) const
{
auto begin = text.begin();
auto end = begin + length;
return MyStr(std::string(begin, end));
}
const char *c_str()
{
return text.c_str();
}
private:
explicit MyStr(std::string s): text(std::move(s)){};
std::string text;
};
struct Other
{
std::string text;
Other(const std::string &s): text(s){};
};
void usage(const char *s)
{
Other other(s); // BAM!!!
}
int main() {
MyStr str("use-after-scope-example");
auto cs = str.substr(2).c_str();
usage(cs);
return 0;
}
如果这很重要的话,这是 C++11,编译器是 g++ (SUSE Linux) 11.1.1 20210617 [revision 79c1185de4]
是的,报错正确(虽然BAM!!!好像错了)。这一行:
auto cs = str.substr(2).c_str();
将 cs
声明为指向字符缓冲区的指针,一旦 str.substr(2)
返回的临时变量被销毁(这发生在表达式的末尾),它就会被删除。
我在我们的代码库 (g++ -fsanitize=address
) 中发现了一个作用域后堆栈使用错误,我想知道这是否是一个有效的问题,我应该去修复每次出现的问题这样的模式,还是地址消毒器的误报?
最小和简化的例子如下:
#include <string>
#include <stdio.h>
struct MyStr
{
MyStr() = default;
MyStr(const char *s) : text(s) {};
MyStr substr(size_t length) const
{
auto begin = text.begin();
auto end = begin + length;
return MyStr(std::string(begin, end));
}
const char *c_str()
{
return text.c_str();
}
private:
explicit MyStr(std::string s): text(std::move(s)){};
std::string text;
};
struct Other
{
std::string text;
Other(const std::string &s): text(s){};
};
void usage(const char *s)
{
Other other(s); // BAM!!!
}
int main() {
MyStr str("use-after-scope-example");
auto cs = str.substr(2).c_str();
usage(cs);
return 0;
}
如果这很重要的话,这是 C++11,编译器是 g++ (SUSE Linux) 11.1.1 20210617 [revision 79c1185de4]
是的,报错正确(虽然BAM!!!好像错了)。这一行:
auto cs = str.substr(2).c_str();
将 cs
声明为指向字符缓冲区的指针,一旦 str.substr(2)
返回的临时变量被销毁(这发生在表达式的末尾),它就会被删除。