Apa itu kesalahan segmentasi? Apakah berbeda dalam C dan C ++? Bagaimana kesalahan segmentasi dan pointer menggantung terkait?
c++
c
segmentation-fault
Rajendra Uppal
sumber
sumber
NullPointerException
.Jawaban:
Kesalahan segmentasi adalah jenis kesalahan khusus yang disebabkan oleh mengakses memori yang "bukan milik Anda." Ini adalah mekanisme pembantu yang mencegah Anda dari merusak memori dan memperkenalkan bug memori yang sulit di-debug. Setiap kali Anda mendapatkan segfault, Anda tahu Anda melakukan sesuatu yang salah dengan memori - mengakses variabel yang telah dibebaskan, menulis ke bagian read-only dari memori, dll. Kesalahan segmentasi pada dasarnya sama di sebagian besar bahasa yang memungkinkan Anda mengacaukan manajemen memori, tidak ada perbedaan utama antara segfault di C dan C ++.
Ada banyak cara untuk mendapatkan segfault, setidaknya dalam bahasa tingkat rendah seperti C (++). Cara umum untuk mendapatkan segfault adalah dengan melakukan dereferensi pointer nol:
Segfault lain terjadi ketika Anda mencoba menulis ke sebagian memori yang ditandai sebagai hanya-baca:
Pointer yang menggantung menunjuk ke sesuatu yang tidak ada lagi, seperti di sini:
Pointer
p
menggantung karena menunjuk ke variabel karakterc
yang tidak ada lagi setelah blok berakhir. Dan ketika Anda mencoba dereference pointer menggantung (seperti*p='A'
), Anda mungkin akan mendapatkan segfault.sumber
c
itu lokal, itu berarti bahwa itu telah didorong pada tumpukan setelah{
dan muncul setelah itu}
. pointer menggantung hanyalah referensi ke offset yang sekarang keluar dari tumpukan. itu sebabnya mengubahnya dalam program sederhana tidak akan pernah memicu segfault. di sisi lain itu dapat menyebabkan segfault dalam kasus penggunaan yang lebih kompleks, di mana panggilan fungsi lain dapat menyebabkan tumpukan untuk tumbuh dan berisi data yang diarahkan oleh pointer menggantung. menulis ke data itu (vars lokal) akan mengarah pada perilaku yang tidak terdefinisi (segfault & Co)SIGSEGV
, jadi saya tidak akan mengharapkan sinyal seperti itu dari campur aduk dengan stack.Perlu dicatat bahwa kesalahan segmentasi tidak disebabkan oleh secara langsung mengakses memori proses lain (ini yang saya dengar kadang-kadang), karena itu tidak mungkin. Dengan memori virtual, setiap proses memiliki ruang alamat virtualnya sendiri dan tidak ada cara untuk mengakses yang lain menggunakan nilai pointer apa pun. Pengecualian untuk ini adalah shared library yang ruang alamat fisiknya sama dipetakan ke (mungkin) alamat virtual dan memori kernel yang berbeda yang bahkan dipetakan dengan cara yang sama di setiap proses (untuk menghindari TLB membilas syscall, saya pikir). Dan hal-hal seperti shmat;) - inilah yang saya anggap sebagai akses 'tidak langsung'. Satu dapat, bagaimanapun, memeriksa bahwa mereka biasanya berada jauh dari kode proses dan kami biasanya dapat mengaksesnya (inilah sebabnya mereka ada di sana,
Namun, kesalahan segmentasi dapat terjadi jika mengakses memori (proses) kita sendiri dengan cara yang tidak benar (misalnya mencoba menulis ke ruang yang tidak dapat ditulisi). Tetapi alasan paling umum untuk itu adalah akses ke bagian ruang alamat virtual yang tidak dipetakan ke fisik sama sekali.
Dan semua ini berkenaan dengan sistem memori virtual.
sumber
Kesalahan segmentasi disebabkan oleh permintaan untuk halaman yang prosesnya tidak terdaftar dalam tabel deskriptornya, atau permintaan yang tidak valid untuk halaman yang telah terdaftar (misalnya permintaan tulis pada halaman read-only).
Pointer menggantung adalah pointer yang mungkin atau mungkin tidak menunjuk ke halaman yang valid, tetapi tidak menunjuk ke segmen memori "tak terduga".
sumber
Sejujurnya, seperti poster-poster lain sebutkan, Wikipedia memiliki artikel yang sangat bagus tentang ini, jadi silakan lihat di sana. Jenis kesalahan ini sangat umum dan sering disebut hal-hal lain seperti Pelanggaran Akses atau Kesalahan Perlindungan Umum.
Mereka tidak berbeda dalam C, C ++ atau bahasa lain yang memungkinkan pointer. Jenis kesalahan ini biasanya disebabkan oleh pointer
sumber
Menurut wikipedia:
sumber
Kesalahan segmentasi juga disebabkan oleh kegagalan perangkat keras, dalam hal ini adalah memori RAM. Ini adalah penyebab yang kurang umum, tetapi jika Anda tidak menemukan kesalahan dalam kode Anda, mungkin memtest dapat membantu Anda.
Solusinya dalam hal ini, ganti RAM.
edit:
Di sini ada referensi: Kesalahan segmentasi oleh perangkat keras
sumber
Kesalahan segmentasi terjadi ketika suatu proses (menjalankan instance dari suatu program) sedang mencoba mengakses alamat memori read-only atau rentang memori yang sedang digunakan oleh proses lain atau mengakses alamat memori yang tidak ada (tidak valid). Masalah Dangling Reference (pointer) berarti mencoba mengakses objek atau variabel yang isinya sudah dihapus dari memori, misalnya:
sumber
Halaman Segmentation_fault Wikipedia memiliki deskripsi yang sangat bagus tentang itu, hanya menunjukkan penyebab dan alasannya. Lihat wiki untuk mendapatkan deskripsi terperinci.
Dalam komputasi, kesalahan segmentasi (sering disingkat menjadi segfault) atau pelanggaran akses adalah kesalahan yang ditimbulkan oleh perangkat keras dengan perlindungan memori, memberitahukan sistem operasi (OS) tentang pelanggaran akses memori.
Berikut ini adalah beberapa penyebab khas kesalahan segmentasi:
Ini pada gilirannya sering disebabkan oleh kesalahan pemrograman yang mengakibatkan akses memori tidak valid:
Mendereferensi atau menetapkan ke pointer yang tidak diinisialisasi (wild pointer, yang menunjuk ke alamat memori acak)
Dereferencing atau menetapkan ke pointer yang dibebaskan (dangling pointer, yang menunjuk ke memori yang telah dibebaskan / tidak dialokasikan / dihapus)
Buffer buffer.
Tumpukan meluap.
Mencoba menjalankan program yang tidak dapat dikompilasi dengan benar. (Beberapa kompiler akan menampilkan file yang dapat dieksekusi meskipun ada kesalahan waktu kompilasi.)
sumber
Dengan kata sederhana: segmentasi kesalahan adalah sistem operasi yang mengirimkan sinyal ke program yang mengatakan bahwa ia telah mendeteksi akses memori ilegal dan secara prematur menghentikan program untuk mencegah memori dari rusak.
sumber
"Kesalahan segmentasi" berarti Anda mencoba mengakses memori yang tidak dapat Anda akses.
Masalah pertama adalah dengan argumen utama Anda. Fungsi utamanya seharusnya
int main(int argc, char *argv[])
, dan Anda harus memeriksa bahwa argc setidaknya 2 sebelum mengakses argv [1].Juga, karena Anda meneruskan float ke printf (yang, dengan cara, dikonversi menjadi ganda ketika lewat ke printf), Anda harus menggunakan specifier format% f. Penentu format% s adalah untuk string (array karakter yang diakhiri '' '0).
sumber
Kesalahan segmentasi atau pelanggaran akses terjadi ketika suatu program mencoba mengakses lokasi memori yang tidak ada, atau mencoba mengakses lokasi memori dengan cara yang tidak diperbolehkan.
Di sini saya [1000] tidak ada, jadi segfault terjadi.
Penyebab kesalahan segmentasi:
sumber
Ada beberapa penjelasan yang baik tentang "kesalahan segmentasi" dalam jawaban, tetapi karena dengan segmentasi kesalahan sering ada dump dari konten memori, saya ingin berbagi di mana hubungan antara bagian "core dumped" dalam kesalahan segmentasi (core dumped) dan memori berasal dari:
Diambil dari sini .
sumber
Ada cukup banyak definisi segmentasi kesalahan, saya ingin mengutip beberapa contoh yang saya temui saat pemrograman, yang mungkin tampak kesalahan konyol, tetapi akan menghabiskan banyak waktu.
Anda bisa mendapatkan segmentasi kesalahan dalam kasus di bawah ini sementara jenis argumet tidak cocok di printf
#include<stdio.h> int main(){
int a = 5; printf("%s",a); return 0; }
keluaran:
Segmentation Fault (SIGSEGV)
ketika Anda lupa mengalokasikan memori ke pointer, tetapi mencoba menggunakannya.
keluaran:
Segmentation Fault (SIGSEGV)
sumber
Arti sederhana
Segmentation fault
adalah bahwa Anda mencoba mengakses beberapa memori yang bukan milik Anda.Segmentation fault
terjadi ketika kami mencoba membaca dan / atau menulis tugas di lokasi memori hanya baca atau mencoba membebaskan memori. Dengan kata lain, kita dapat menjelaskan ini sebagai semacam korupsi memori.Di bawah ini saya menyebutkan kesalahan umum yang dilakukan oleh programmer yang menyebabkan
Segmentation fault
.scanf()
dengan cara yang salah (lupa menempatkan&
).printf()
danscanf()
'sumber