c++ - 析构函数给出“可能未初始化”用于删除资源
问题描述
下面的代码是一个模拟数组的基本类。
析构函数使用 g++ 发出警告:
warning: ‘*((void*)(&<anonymous>)+8).s_array<int>::my_array’ may be used uninitialized in this function [-Wmaybe-uninitialized]
delete [] my_array;
我是否设置错误?像这样使用变量“初始化”是我过去的做法,没有任何警告。
template<class TYPE>
class s_array{
private:
int my_size;
TYPE * my_array;
bool initialized;
public:
s_array(){initialized=false;}
s_array(int size){
initialized=true;
my_size=size;
my_array=new TYPE[my_size];
}
s_array(const s_array& source){
if (source.initialized==true){
initialized=true;
my_size=source.my_size;
my_array=new TYPE[my_size];
for (int i=0; i<my_size; i++)
my_array[i]=source.my_array[i];
}
else
initialized=false;
}
s_array& operator= (const s_array& source){
if (&source!=this){
if (source.initialized==true){
initialized=true;
my_size=source.my_size;
my_array=new TYPE[my_size];
for (int i=0; i<my_size; i++)
my_array[i]=source.my_array[i];
}
else
initialized=false;
}
return *this;
}
~s_array(){
if (initialized)
delete [] my_array;
}
TYPE operator [](int i) const {
assert(i>=0 && i<my_size);
return my_array[i];
}
TYPE & operator [](int i) {
assert(i>=0 && i<my_size);
return my_array[i];
}
};
特别是,初始化的流程是否存在阻止编译器看到它对应于正在初始化的 my_array 的内容?
解决方案
编译器会看到,如果您使用默认构造函数创建对象,则my_array
不会初始化。默认构造的对象可以被销毁,并且在析构函数中my_array
,如果未初始化,您访问的值将具有未定义的行为。
initialized
当然,您可能已经建立了一个仅在初始化时才成立的不变量my_array
,但编译器将无法证明这一点。
您可以通过删除成员来简化您的类initialized
,并将其所有比较替换为比较my_array
(nullptr
除了析构函数中的那个;该检查变得多余),并在默认构造函数中初始化my_array
为。nullptr
后一个更改解决了警告。
推荐阅读
- regex - 正则表达式仅匹配“第 1 组”。而不是“完全匹配”
- azure - 使用客户端凭据流,无需从同一租户内的任何应用程序委托访问即可生成访问令牌
- mariadb - 寻求仅在一个 DC 中实施备份的解决方案
- amazon-web-services - 使用 AWS SQS 的最有效方式(使用 Golang)
- c# - 使用 python c-api 调用 PyErr_Print 后如何访问 sys.stderr
- heroku - 使用 @sentry/webpack-plugin 和 heroku 的哨兵
- excel - 为什么 Object 会抛出 Variant 没有的错误?
- amazon-s3 - 将 Amazon S3 限制为 CloudFront 和 http 引荐来源网址
- java - onPause 中的 unregisterReceiver(receiver) 导致接收方不注册
- regex - 正则表达式匹配换行符后的所有内容