为什么用三元初始化 class 会导致双重释放?
Why does initializing a class with a ternary if cause a double-free?
在启用 clang-analyzer 的情况下使用 clang 编译以下代码时:
#include <stdlib.h>
struct Buffer {
unsigned char *buf;
Buffer() : buf(0) {}
Buffer(const Buffer &that) {
buf = new unsigned char;
*buf = *that.buf;
}
Buffer(Buffer &&);
~Buffer() { delete buf; }
Buffer &operator=(const Buffer &that) = delete;
Buffer &operator=(Buffer &&that) = delete;
};
Buffer func() {
Buffer a;
return a;
}
int main() { Buffer a = 1 ? func() : Buffer(); }
使用命令:
scan-build clang++ main.cc -std=c++17
产生以下错误:
main.cc:10:17: warning: Attempt to free released memory
~Buffer() { delete buf; }
但是,当用 Buffer a = func();
(没有三元 if)初始化 a
时,错误消失了。此外,使用 -std=c++11
也会使错误消失。
为什么会这样?
程序格式错误,因为使用了移动构造函数,但未定义这违反了单一定义规则。程序中的这个错误可能导致扫描仪诊断误报。
未使用复制构造函数,但它已损坏,因为它可能通过空指针进行间接访问。
在启用 clang-analyzer 的情况下使用 clang 编译以下代码时:
#include <stdlib.h>
struct Buffer {
unsigned char *buf;
Buffer() : buf(0) {}
Buffer(const Buffer &that) {
buf = new unsigned char;
*buf = *that.buf;
}
Buffer(Buffer &&);
~Buffer() { delete buf; }
Buffer &operator=(const Buffer &that) = delete;
Buffer &operator=(Buffer &&that) = delete;
};
Buffer func() {
Buffer a;
return a;
}
int main() { Buffer a = 1 ? func() : Buffer(); }
使用命令:
scan-build clang++ main.cc -std=c++17
产生以下错误:
main.cc:10:17: warning: Attempt to free released memory
~Buffer() { delete buf; }
但是,当用 Buffer a = func();
(没有三元 if)初始化 a
时,错误消失了。此外,使用 -std=c++11
也会使错误消失。
为什么会这样?
程序格式错误,因为使用了移动构造函数,但未定义这违反了单一定义规则。程序中的这个错误可能导致扫描仪诊断误报。
未使用复制构造函数,但它已损坏,因为它可能通过空指针进行间接访问。