Apa itu kesalahan segmentasi? Apakah berbeda dalam C dan C ++? Bagaimana kesalahan segmentasi dan pointer menggantung terkait?
NullPointerException
.
Apa itu kesalahan segmentasi? Apakah berbeda dalam C dan C ++? Bagaimana kesalahan segmentasi dan pointer menggantung terkait?
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:
int *p = NULL;
*p = 1;
Segfault lain terjadi ketika Anda mencoba menulis ke sebagian memori yang ditandai sebagai hanya-baca:
char *str = "Foo"; // Compiler marks the constant string as read-only
*str = 'b'; // Which means this is illegal and results in a segfault
Pointer yang menggantung menunjuk ke sesuatu yang tidak ada lagi, seperti di sini:
char *p = NULL;
{
char c;
p = &c;
}
// Now p is dangling
Pointer p
menggantung karena menunjuk ke variabel karakter c
yang tidak ada lagi setelah blok berakhir. Dan ketika Anda mencoba dereference pointer menggantung (seperti *p='A'
), Anda mungkin akan mendapatkan segfault.
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.
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".
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
Menurut wikipedia:
Kesalahan segmentasi terjadi ketika suatu program mencoba mengakses lokasi memori yang tidak diizinkan untuk diakses, atau mencoba mengakses lokasi memori dengan cara yang tidak diizinkan (misalnya, berusaha menulis ke lokasi baca-saja, atau untuk menimpa bagian dari sistem operasi).
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
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:
int *arr = new int[20];
delete arr;
cout<<arr[1]; //dangling problem occurs here
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.)
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.
"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).
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.
/* "Array out of bounds" error
valid indices for array foo
are 0, 1, ... 999 */
int foo[1000];
for (int i = 0; i <= 1000 ; i++)
foo[i] = i;
Di sini saya [1000] tidak ada, jadi segfault terjadi.
Penyebab kesalahan segmentasi:
it arise primarily due to errors in use of pointers for virtual memory addressing, particularly illegal access.
De-referencing NULL pointers – this is special-cased by memory management hardware.
Attempting to access a nonexistent memory address (outside process’s address space).
Attempting to access memory the program does not have rights to (such as kernel structures in process context).
Attempting to write read-only memory (such as code segment).
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:
Dari sekitar tahun 1955 hingga 1975 - sebelum memori semikonduktor - teknologi dominan dalam memori komputer menggunakan donat magnetik kecil yang digantung pada kabel tembaga. Donat dikenal sebagai "inti ferit" dan memori utama yang dikenal sebagai "memori inti" atau "inti".
Diambil dari sini .
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.
#include<stdio.h>
typedef struct{
int a;
}myStruct;
int main(){
myStruct *s;
/* few lines of code */
s->a = 5;
return 0;
}
keluaran: Segmentation Fault (SIGSEGV)
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 &
).int num;
scanf("%d", num);// must use &num instead of num
int *num;
printf("%d",*num); //*num should be correct as num only
//Unless You can use *num but you have to point this pointer to valid memory address before accessing it.
char *str;
//Stored in read only part of data segment
str = "GfG";
//Problem: trying to modify read only memory
*(str+1) = 'n';
// allocating memory to num
int* num = malloc(8);
*num = 100;
// de-allocated the space allocated to num
free(num);
// num is already freed there for it cause segmentation fault
*num = 110;
printf()
dan scanf()
'