﻿# V780\. The object of non\-passive \(non\-PDS\) type cannot be used with the function\.

Анализатор обнаружил опасную работу со сложными типами\. Если объект не является Passive Data Structure \(PDS\), то нельзя использовать низкоуровневые функции по работе с памятью: memset, memcpy и т\.д\. Это может нарушить логику работы класса и привести к утечке памяти, двойному очищению одного ресурса или Undefined Behavior\.

Пример классов, над которыми нельзя совершать такие действия: std::vector, std::string и другие подобные контейнеры\.

Иногда такая диагностика находит опечатки\. Рассмотрим пример:

```cpp
struct Buffer {
  std::vector<char>* m_data;

  void load(char *buf, size_t len) {
    m_data->resize(len);
    memcpy(&m_data[0], buf, len);
  }
};
```

Функция 'memcpy' копирует данные не в содержимое контейнера, а в объект, на который указывает 'm\_data'\. Такой код нужно переписать следующим образом:

```cpp
memcpy(&(*m_data)[0], buf, len);
```

или:

```cpp
memcpy(m_data->data(), buf, len);
```

Другой способ ошибиться \- это использовать memset/memcpy для структуры, полями которой являются non\-PDS объекты\. Рассмотрим пример:

```cpp
struct Buffer {
  std::vector<char> m_data;
  ....
};

void F() {
  Buffer a;
  memset(&a, 0, sizeof(Buffer));
  ....
}
```

Чтобы избежать таких ошибок можно рекомендовать использовать value initialization\. Такой подход корректно работает и с POD\-данными, и с объектами с нетривиальным конструктором\.

Для копирования можно положиться на генерируемый компилятором конструктор копирования или написать свой\.

Анализатор также ищет структуры, использование memset/memcpy над которыми может быть опасно, исходя из их логики или представления в памяти\. К первому случаю относятся классы, в которых одновременно есть указатели, конструкторы и деструкторы\. Если в классе содержится нетривиальная работа с указателями \(например, управление памятью или ресурсом\), то нельзя использовать для него memcpy/memset\. Пример такого класса:

```cpp
struct Buffer {
  char *buf;

  Buffer() : buf(new char[16]) {}
  ~Buffer() { delete[] buf; }
};

Buffer buf1, buf2;
memcpy(&buf1, &buf2, sizeof(Buffer));
```



Ко второму случаю относятся классы, не являющиеся standard layout:

```cpp
struct BufferImpl {
  virtual bool read(char *, size_t) { return false; }
};

struct Buffer {
  BufferImpl impl;
};

Buffer buf1, buf2;
memcpy(&buf1, &buf2, sizeof(Buffer));
```