деструктор дает "может быть использован неинициализирован" для удаления ресурса - PullRequest
0 голосов
/ 09 февраля 2019

Приведенный ниже код является базовым классом для имитации массива.

Деструктор выдает предупреждение с помощью g ++:

warning: ‘*((void*)(&<anonymous>)+8).s_array<int>::my_array’ may be used uninitialized in this function [-Wmaybe-uninitialized]
       delete [] my_array;

Я неправильно это настраиваю?Используя переменную «initialized», вот так, как я делал это в прошлом, без предупреждений.

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];
    }

};

В частности, есть ли что-то в потоке с initialized, которое мешает компилятору видетьчто это соответствует инициализации my_array?

1 Ответ

0 голосов
/ 09 февраля 2019

Компилятор видит, что если вы создаете объект с помощью конструктора по умолчанию, то my_array не инициализируется.Созданный по умолчанию объект может быть уничтожен, и в деструкторе вы получаете доступ к значению my_array, которое будет иметь неопределенное поведение, если оно не будет инициализировано.

Конечно, вы, возможно, установили инвариант, что initializedтолько true, если my_array инициализирован, но компилятор не сможет доказать это.


Вы можете упростить свой класс, удалив член initialized, и заменить все его сравнения сравнением *От 1011 * до nullptr (кроме той, которая находится в деструкторе; эта проверка становится избыточной), и инициализируйте my_array до nullptr в конструкторе по умолчанию.Последнее изменение устраняет предупреждение.

...