Memori dinamik C++


Memahami cara memori dinamik berfungsi dalam C++ adalah penting untuk menjadi pengaturcara C++ yang cekap. Memori dalam program C++ terbahagi kepada dua bahagian:

  • Timbunan: Semua pembolehubah yang diisytiharkan di dalam fungsi akan menduduki memori tindanan.

  • Heap: Ini ialah memori yang tidak digunakan dalam atur cara dan boleh digunakan untuk memperuntukkan memori secara dinamik semasa atur cara sedang berjalan.

Banyak kali, anda tidak boleh meramalkan terlebih dahulu berapa banyak memori yang diperlukan untuk menyimpan maklumat tertentu dalam pembolehubah yang ditentukan Saiz memori yang diperlukan perlu ditentukan pada masa jalan.

Dalam C++, anda boleh memperuntukkan memori pada timbunan pada masa jalan untuk pembolehubah jenis tertentu menggunakan pengendali khas, yang mengembalikan alamat ruang yang diperuntukkan. Operator ini ialah pengendali baharu.

Jika anda tidak perlu memperuntukkan memori secara dinamik, anda boleh menggunakan operator padam untuk memadamkan memori yang diperuntukkan oleh operator baharu sebelum ini.

pengendali baharu dan padam

Berikut ialah sintaks umum untuk menggunakan operator baharu untuk memperuntukkan memori secara dinamik untuk sebarang jenis data:

new data-type;

Di sini, data - jenis boleh menjadi mana-mana jenis data terbina dalam termasuk tatasusunan, atau mana-mana jenis data yang ditentukan pengguna termasuk kelas atau struktur. Mari kita lihat jenis data terbina dalam dahulu. Sebagai contoh, kita boleh menentukan penunjuk untuk menaip dua kali ganda dan kemudian meminta memori, yang diperuntukkan pada masa pelaksanaan. Kita boleh mencapainya menggunakan operator baharu seperti berikut:

double* pvalue  = NULL; // 初始化为 null 的指针
pvalue  = new double;   // 为变量请求内存

Jika kawasan storan percuma telah kehabisan, peruntukan memori mungkin tidak berjaya. Oleh itu, adalah disyorkan untuk menyemak sama ada pengendali baharu mengembalikan penunjuk NULL dan mengambil tindakan yang sesuai berikut:

double* pvalue  = NULL;
if( !(pvalue  = new double ))
{
   cout << "Error: out of memory." <<endl;
   exit(1);

}

malloc() Fungsi muncul dalam bahasa C dan masih wujud dalam C++ , tetapi Adalah disyorkan untuk tidak menggunakan fungsi malloc() sebanyak mungkin. Kelebihan utama new berbanding dengan fungsi malloc() ialah new bukan sahaja memperuntukkan memori, ia juga mencipta objek.

Pada bila-bila masa, apabila anda merasakan pembolehubah yang telah diperuntukkan memori secara dinamik tidak lagi diperlukan, anda boleh menggunakan operator padam untuk melepaskan memori yang didudukinya, seperti berikut:

delete pvalue;        // 释放 pvalue 所指向的内存

Konsep di atas digunakan dalam contoh berikut, yang menunjukkan cara menggunakan operator baharu dan padam:

#include <iostream>
using namespace std;

int main ()
{
   double* pvalue  = NULL; // 初始化为 null 的指针
   pvalue  = new double;   // 为变量请求内存
 
   *pvalue = 29494.99;     // 在分配的地址存储值
   cout << "Value of pvalue : " << *pvalue << endl;

   delete pvalue;         // 释放内存

   return 0;
}

Apabila kod di atas disusun dan dilaksanakan, ia menghasilkan keputusan berikut:

Value of pvalue : 29495

Peruntukan memori dinamik untuk tatasusunan

Andaikan kita ingin memperuntukkan memori untuk tatasusunan aksara (rentetan 20 aksara), kita boleh menggunakan sintaks dalam contoh di atas untuk memperuntukkan memori secara dinamik untuk tatasusunan, seperti Paparan berikut:

char* pvalue  = NULL;   // 初始化为 null 的指针
pvalue  = new char[20]; // 为变量请求内存

Untuk memadam tatasusunan yang baru kami buat, pernyataannya adalah seperti berikut:

delete [] pvalue;        // 删除 pvalue 所指向的数组

Berikut ialah sintaks umum pengendali baharu, yang boleh memperuntukkan memori untuk tatasusunan berbilang dimensi, seperti berikut:

int ROW = 2;
int COL = 3;
double **pvalue  = new double* [ROW]; // 为行分配内存

// 为列分配内存
for(int i = 0; i < COL; i++) {
    pvalue[i] = new double[COL];
}

Lepaskan memori tatasusunan berbilang dimensi:

for(int i = 0; i < COL; i++) {
    delete[] pvalue[i];
}
delete [] pvalue;

Peruntukan memori dinamik objek

Objek tidak berbeza daripada jenis data ringkas. Sebagai contoh, lihat kod berikut, di mana kita akan menggunakan pelbagai objek untuk menjelaskan konsep ini:

#include <iostream>
using namespace std;

class Box
{
   public:
      Box() { 
         cout << "调用构造函数!" <<endl; 
      }
      ~Box() { 
         cout << "调用析构函数!" <<endl; 
      }
};

int main( )
{
   Box* myBoxArray = new Box[4];

   delete [] myBoxArray; // Delete array

   return 0;
}

Jika anda ingin memperuntukkan memori untuk tatasusunan yang mengandungi empat objek Kotak, pembina akan dipanggil 4 kali, begitu juga apabila objek dipadamkan, pemusnah juga akan dipanggil bilangan kali yang sama (4 kali).

Apabila kod di atas disusun dan dilaksanakan, ia menghasilkan keputusan berikut:

调用构造函数!
调用构造函数!
调用构造函数!
调用构造函数!
调用析构函数!
调用析构函数!
调用析构函数!
调用析构函数!