Apakah memori yang dialokasikan ke variabel statis global yang ditentukan dalam cpp dibebaskan setelah instance kelasnya dihapus di C++?

Saya memiliki kelas yang metodenya ditentukan dalam file example.cpp dan kelasnya ditentukan dalam example.h. Ada penunjuk global statis yang ditentukan dalam file example.cpp. (Saya perlu penunjuk ini didefinisikan sebagai penunjuk global statis di .cpp saat dipanggil dalam rutinitas layanan interupsi statis yang berjalan pada sistem bare-metal.) Saya bertanya-tanya kapan sebuah instance dari kelas ini dihapus, apakah memori yang dialokasikan ke penunjuk global statis ini, yang didefinisikan di luar kelas (di dalam file cpp sebagai variabel global statis), juga dikosongkan? Saya khawatir tentang masalah kebocoran memori. (tolong jangan menyarankan apa pun dengan smart pointer, terima kasih)

// example.cpp
#include <example.h>
static example* ptr;
example::example(){ prt = this; }
example::~example(){}

// example.h
class example
{
public:
example();
virtual ~example();
int a;
};

//main.c
void main(void)
{
  while(1){
           example eg1;
           delete &eg1;
           }
  //Has all the memory allocated to eg1 been freed up including the global static variable(a pointer)?
}

Saya memahami bahwa (int a) di dalam objek pasti akan dibebaskan setelah objek dihapus, tetapi apakah memori yang dialokasikan ke penunjuk statis global itu sendiri (contoh statis* ptr) juga akan dibebaskan? (Saya berasumsi) Jika variabel global statis tidak dibagikan oleh semua instance kelas, apakah ia benar-benar mengalokasikan memori ke variabel global statis ini tetapi tidak mengosongkannya setelah instance dihapus? Apakah ini akan menyebabkan kebocoran memori?

Ini pertama kalinya saya melontarkan pertanyaan di sini. Mohon maaf sebelumnya jika ada yang kurang jelas.


person TyL    schedule 12.03.2015    source sumber
comment
Siapa yang tidak hanya menggunakan pola desain singleton?   -  person Lawrence Aiello    schedule 12.03.2015
comment
baru dan hapus harus digunakan berpasangan, sekarang apakah Anda melihat apa masalah kode Anda?   -  person billz    schedule 12.03.2015
comment
Saya yakin Anda sadar bahwa pernyataan delete &eg1 Anda salah besar dan sama sekali tidak perlu...   -  person Lightness Races in Orbit    schedule 13.03.2015


Jawaban (4)


Pertama-tama, jika Anda menjalankan kode yang Anda posting, Anda mendapatkan yang berikut:

malloc: *** error for object 0x7fff560a8830: pointer being freed was not allocated

Ini karena Anda menghapus &eg1 tanpa terlebih dahulu mengalokasikan memorinya di heap menggunakan new.

Kedua, destruktor/delete hanya akan membersihkan memori yang terkait dengan objek example. Tidak ada kewajiban untuk membersihkan static example* ptr.

Melihat hal ini dengan cara lain, destruktor dan delete dimaksudkan untuk membersihkan data yang dialokasikan secara dinamis, yaitu data yang berada di heap, bukan hanya di tumpukan pemanggilan fungsi saat ini. Sebaliknya, static example* ptr adalah global, yang berada di segmen data global, terpisah dari heap dan stack.

Dengan demikian, Anda dapat melihat bahwa destruktor objek delete dan example tidak akan mengosongkan memori yang dialokasikan untuk menyimpan pointer itu sendiri, karena keduanya tidak memiliki yurisdiksi untuk melakukannya.

Sunting -------------

Seperti yang telah dinyatakan oleh orang lain, variabel static berlaku sepanjang masa program, sehingga variabel tersebut tidak akan terhapus hingga program Anda dihentikan.

Ada banyak hal yang bisa dipetik di sini! static mungkin membingungkan pada awalnya, namun pengetahuan yang baik akan sangat bermanfaat.

person CLL    schedule 12.03.2015

Apa pun yang dinyatakan sebagai static berlaku sepanjang masa program. Itu dibangun sebelum kemungkinan penggunaan pertama, dan dihancurkan pada saat yang tidak ditentukan sepenuhnya selama penghentian program (yaitu, setelah main kembali atau exit dipanggil).

Selain itu, menghancurkan sebuah pointer (yang tidak cerdas) tidak pernah akan menghancurkan benda yang ditunjuk oleh pointer tersebut. Anda harus memanggil delete secara eksplisit pada penunjuk jika Anda ingin mengosongkan sumber daya yang ditunjuknya. (Atau gunakan penunjuk pintar. Lakukan. Itu lebih baik.)

person rici    schedule 12.03.2015
comment
Terima kasih telah menjawab tetapi saya mungkin menyesatkan Anda di sini. Saya tidak tertarik dengan memori penunjuk yang menunjuk tetapi sebenarnya memori yang dialokasikan untuk menyimpan penunjuk itu sendiri. Saya hanya mengubah kodenya sedikit agar lebih jelas. - person TyL; 13.03.2015
comment
@TyL: Itu adalah subjek paragraf pertama saya. Menurut definisi, masa pakai sesuatu yang statis adalah masa pakai program. - person rici; 13.03.2015
comment
Apakah Anda mengatakan variabel global statis juga dibagikan dengan semua instance kelas ini? (Saya pikir itu hanya dapat dibagikan ketika didefinisikan di dalam kelas sebagai anggota, bukan di luar kelas). Jika tidak, variabel statis tidak akan mengetahui berapa banyak instance kelas ini yang akan saya buat? Apakah menurut Anda loop while(1) di main.c saya akan menyebabkan kebocoran memori? - person TyL; 13.03.2015
comment
@tyl: Hanya ada satu variabel global statis. Menurut Anda mengapa ini terkait dengan turunan kelas? Itu hanya definisi global tanpa keterkaitan eksternal. - person rici; 13.03.2015
comment
Oke. Saya mengerti sekarang. Terimakasih banyak!!!!!!! Saya terus berpikir itu akan dibuat setelah sebuah instance dibuat.... - person TyL; 13.03.2015
comment
Urutan penghancuran statika tidak ditentukan; itu dalam urutan konstruksi terbalik. Dan itu terjadi setelah main kembali. - person Alan Stokes; 13.03.2015
comment
@AlanStokes: Ya, tetapi urutan pembuatan statika di unit terjemahan yang berbeda tidak ditentukan, dan akibatnya urutan penghancurannya juga tidak. Mungkin tidak disebutkan secara lengkap akan lebih tepat. - person rici; 13.03.2015

Secara umum, variabel global statis bukanlah variabel anggota, jadi ketika suatu kelas dialokasikan atau dihapus, tidak ada dampak terhadap variabel global statis, kecuali anggota kelas secara eksplisit mengalokasikan atau membatalkan alokasi memori untuk variabel global statis.

Dalam contoh Anda, Anda hanya menugaskan pointer ke variabel global, dan tidak mengalokasikan memori baru. Oleh karena itu, Anda tidak perlu membebaskannya secara eksplisit.

Selain itu, Anda tidak perlu memanggil delete di main(), karena misalnya1 adalah variabel lokal. Ketika main kembali, destruktor eg1 akan dipanggil secara otomatis.

person Vivek    schedule 12.03.2015
comment
Terima kasih. Ini sangat membantu. Apakah Anda mengatakan variabel global statis juga dibagikan dengan semua instance kelas ini? (Saya pikir itu hanya dapat dibagikan ketika ditentukan di dalam kelas, bukan di luar kelas) - person TyL; 13.03.2015
comment
Variabel global statis dapat diakses oleh semua instance kelas dan akan ditulis ulang setiap kali objek contoh baru dibuat. Bahkan jika variabel tersebut dijadikan variabel anggota kelas statis, variabel tersebut akan ditulis ulang dengan cara yang sama. Oleh karena itu, alih-alih menugaskan variabel global di konstruktor kelas, menugaskannya ke &eg1 di main() akan memastikan variabel tersebut tidak ditimpa. - person Vivek; 13.03.2015

Tidak. Objek penunjuk static tidak memiliki tautan intrinsik ke kelas example, dan tentu saja tidak ada tautan intrinsik ke objek eg1. Jika sistem menghancurkan ptr hanya karena eg1 keluar dari cakupannya, bahasanya akan sangat rusak.

person Lightness Races in Orbit    schedule 12.03.2015