logo

оператори new і delete у C++ для динамічної пам’яті

Динамічний розподіл пам’яті в C/C++ означає виконання програмістом розподілу пам’яті вручну. Динамічно виділена пам'ять виділяється на Купа, а нестатичні та локальні змінні отримують пам’ять Стек (Відноситься до Розмітка пам'яті C Програми для деталей).

Що таке програми?

  • Одним із способів використання динамічно розподіленої пам’яті є виділення пам’яті змінного розміру, що неможливо з виділеною компілятором пам’яттю, за винятком масиви змінної довжини .
  • Найважливішим використанням є гнучкість, яка надається програмістам. Ми можемо вільно виділяти та звільняти пам’ять, коли вона нам потрібна і коли вона нам більше не потрібна. Є багато випадків, коли ця гнучкість допомагає. Приклади таких випадків є дерево і т.д.

Чим він відрізняється від пам’яті, виділеної для звичайних змінних?



Для звичайних змінних, таких як int a, char str[10] тощо, пам’ять автоматично виділяється та звільняється. Для динамічно виділеної пам’яті, наприклад int *p = new int[10], програміст зобов’язаний звільнити пам’ять, коли вона більше не потрібна. Якщо програміст не звільняє пам’ять, це спричиняє a витік пам'яті (пам'ять не звільняється, доки програма не завершить роботу).

Як розподіляється/звільняється пам'ять у C++?
C використовує malloc() і calloc() функція для динамічного розподілу пам’яті під час виконання та використовує функцію free() для звільнення динамічно виділеної пам’яті. C++ підтримує ці функції, а також має два оператори новий і видалити, які краще та легше виконують завдання розподілу та звільнення пам’яті.

новий оператор

Новий оператор позначає запит на виділення пам'яті у Free Store. Якщо доступно достатньо пам’яті, оператор new ініціалізує пам’ять і повертає адресу нововиділеної та ініціалізованої пам’яті до змінної покажчика.

Синтаксис використання нового оператора

конвертувати з char в int java
pointer-variable =   new   data-type;>

Тут змінна-вказівник є вказівником типу data-type. Тип даних може бути будь-яким вбудованим типом даних, включаючи масив, або будь-яким типом даних, визначеним користувачем, включаючи структуру та клас.
приклад:

// Pointer initialized with NULL // Then request memory for the variable int *p = NULL;  p = new int;    OR  // Combine declaration of pointer  // and their assignment int *p = new int;>
C++
// C++ program to demonstrate how to create dynamic variable // using new #include  #include  using namespace std; int main() {  // pointer to store the address returned by the new  int* ptr;  // allocating memory for integer  ptr = new int;  // assigning value using dereference operator  *ptr = 10;  // printing value and address  cout << 'Address: ' << ptr << endl;  cout << 'Value: ' << *ptr;  return 0; }>

Вихід
Address: 0x162bc20 Value: 10>

Ініціалізація пам'яті: Ми також можемо ініціалізувати пам'ять для вбудованих типів даних за допомогою оператора new. Для користувацьких типів даних потрібен конструктор (з типом даних як вхідні дані) для ініціалізації значення. Ось приклад ініціалізації обох типів даних:

pointer-variable =   new   data-type(value);>

приклад:

C++
// C++ program to illustrate how to initialize a dynamic // variable with allocation #include  #include  using namespace std; // Custom data type with constructor to take initial value struct cust {  int p;  cust(int q)  : p(q)  {  }  cust() = default; }; int main() {  // creating inbuit data types with initial value  int* p = new int(25);  float* q = new float(75.25);  // Works fine, doesn’t require constructor  cust* var1 = new cust;  // OR  // Works fine, doesn’t require constructor  var1 = new cust();  // Notice error if you comment this line  cust* var = new cust(25);  cout << *p << ' ' << *q << ' ' << var->p;  повернути 0; }>

Вихід
25 75.25 25>

Виділити блок пам'яті: новий оператор також використовується для виділення блоку (масиву) пам’яті типу тип даних .

pointer-variable =   new   data-type[size];>

де розмір (змінна) визначає кількість елементів у масиві.

приклад:

obj в java
int *p = new int[10]>

Динамічно виділяє пам’ять для 10 безперервних цілих чисел типу int і повертає вказівник на перший елемент послідовності, якому присвоєно top (вказівник). p[0] відноситься до першого елемента, p[1] відноситься до другого елемента і так далі.

динамічний розподіл пам'яті

Звичайне оголошення масиву проти використання нового
Існує різниця між оголошенням звичайного масиву та виділенням блоку пам’яті за допомогою new. Найважливіша відмінність полягає в тому, що звичайні масиви звільняються компілятором (якщо масив локальний, то звільняється, коли функція повертається або завершується). Однак динамічно виділені масиви завжди залишаються там, доки їх не звільнить програміст або програма не завершить роботу.

Що робити, якщо під час виконання недостатньо пам’яті?
Якщо в купі недостатньо пам’яті для виділення, новий запит вказує на помилку, викидаючи виняток типу std::bad_alloc, якщо тільки nothrow не використовується з оператором new, у цьому випадку він повертає вказівник NULL (прокрутіть до розділу Виняток обробка нового оператора в це стаття). Таким чином, може бути гарною ідеєю перевірити змінну вказівника, створену new перед використанням його програми.

int *p = new(nothrow) int; if (!p) {  cout << 'Memory allocation failed
'; }>

оператор видалення

Оскільки звільнення динамічно виділеної пам’яті є обов’язком програміста, програмістам надається оператор видалення мовою C++.

Синтаксис:

// Release memory pointed by pointer-variable   delete   pointer-variable;>

Тут змінна покажчика є покажчиком, який вказує на створений об’єкт даних новий .

приклади:

розмітка виносок
delete p; delete q;>

Щоб звільнити динамічно виділений масив, на який вказує змінна-покажчик, використовуйте наступну форму видалити :

  // Release block of memory     // pointed by pointer-variable  delete[] pointer-variable;     Example:    // It will free the entire array    // pointed by p.   delete[] p;>
CPP
// C++ program to illustrate dynamic allocation // and deallocation of memory using new and delete #include  using namespace std; int main() {  // Pointer initialization to null  int* p = NULL;  // Request memory for the variable  // using new operator  p = new (nothrow) int;  if (!p)  cout << 'allocation of memory failed
';  else {  // Store value at allocated address  *p = 29;  cout << 'Value of p: ' << *p << endl;  }  // Request block of memory  // using new operator  float* r = new float(75.25);  cout << 'Value of r: ' << *r << endl;  // Request block of memory of size n  int n = 5;  int* q = new (nothrow) int[n];  if (!q)  cout << 'allocation of memory failed
';  else {  for (int i = 0; i < n; i++)  q[i] = i + 1;  cout << 'Value store in block of memory: ';  for (int i = 0; i < n; i++)  cout << q[i] << ' ';  }  // freed the allocated memory  delete p;  delete r;  // freed the block of allocated memory  delete[] q;  return 0; }>

Вихід
Value of p: 29 Value of r: 75.25 Value store in block of memory: 1 2 3 4 5>

Часова складність: O(n), де n - заданий розмір пам'яті.

Пов'язані статті:

  • Тест на новий і видалити
  • видалити або безкоштовно