如何解决Gcc 自定义运算符 new[] 和 delete[] 对于对齐的类来说是错误的 - 地址清理程序会报告缓冲区溢出
基本上当类有对齐要求和自定义运算符 new[]
和 delete[]
时,然后在 gcc 上会发生不好的事情并且地址清理器报告缓冲区溢出:
MCVE:
#include <iostream>
#include <memory>
class EndlineOnDone {
std::ostream& out;
public:
EndlineOnDone(std::ostream& out) : out{out} {}
~EndlineOnDone()
{
out << std::endl;
}
std::ostream& stream() { return out; }
};
#define VAR(x) " " #x "=[" << x << "]"
#define LOG EndlineOnDone(std::cout).stream() << __PRETTY_FUNCTION__
std::ostream& operator<<(std::ostream& out,std::align_val_t a)
{
return out << static_cast<size_t>(a);
}
class alignas(32) Foo
{
public :
double x,y,z;
void * operator new (size_t s,std::align_val_t a)
{
auto p = aligned_alloc(static_cast<size_t>(a),s);
LOG << VAR(p) << VAR(s) << VAR(a);
return p;
}
void operator delete (void * p,size_t s,std::align_val_t a)
{
LOG << VAR(p) << VAR(s) << VAR(a);
if (p) free(p);
}
#if 1
void * operator new[ ] (size_t s,s);
LOG << VAR(p) << VAR(s) << VAR(a);
return p;
}
void operator delete[ ] (void *p,std::align_val_t a)
{
LOG << VAR(p) << VAR(s) << VAR(a);
if (p) free(p);
}
#endif
};
int main()
{
{
LOG << " std::make_unique<Foo>";
auto p = std::make_unique<Foo>();
}
{
LOG << " std::make_unique<Foo[]>";
auto p = std::make_unique<Foo[]>(3);
}
}
gcc 日志(无地址清理器):
int main() std::make_unique<Foo>
static void* Foo::operator new(size_t,std::align_val_t) p=[0x21d6ec0] s=[32] a=[32]
static void Foo::operator delete(void*,size_t,std::align_val_t) p=[0x21d6ec0] s=[32] a=[32]
int main() std::make_unique<Foo[]>
static void* Foo::operator new [](size_t,std::align_val_t) p=[0x21d6f40] s=[96] a=[32]
static void Foo::operator delete [](void*,std::align_val_t) p=[0x21d6f40] s=[3616] a=[32]
请注意,s
的 Foo[]
值与 new[]
和 delete[]
操作不匹配。
Address sanitizer 报告缓冲区溢出。
叮当声很好
问题
有没有办法解决这个问题?例如添加一些编译器标志(见下面的编辑部分)。
这是一个已知问题吗?我不知道如何找到相应的错误报告(IMO 是 gcc 错误)。
编辑/线索
好的,我有一个解决方法。添加显式析构函数 ~Foo() {}
修复了这个问题:https://godbolt.org/z/WoM91Y(使用 ~Foo() = default;
不能修复它)。
解决方法
有趣的是,添加默认的非内联析构函数 (Foo::~Foo()=default;
) 也解决了这个问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。