สับสนกับพอยน์เตอร์และหน่วยความจำเสมือนใน C

ฉันคิดว่าคำถามของฉันง่ายมากแต่ฉันไม่สามารถหาคำตอบได้ ตามความเข้าใจของฉันเกี่ยวกับหน่วยความจำเสมือน:

ทุกกระบวนการจะได้รับพื้นที่ที่อยู่ติดกันซึ่งแมปกับหน่วยความจำกายภาพ

ดังนั้นโค้ดที่ฉันเขียนในโปรแกรมของฉันควรจะสามารถเข้าถึงได้ทุกที่ในหน่วยความจำเสมือนที่มอบให้ ดังนั้นฉันจึงเขียนโค้ดต่อไปนี้ในภาษา C ซึ่งส่งข้อยกเว้นประเภท "ข้อยกเว้นการละเมิดการเข้าถึง"

ฉันจะขอบคุณถ้ามีคนอธิบายเหตุผลให้ฉันฟัง

นี่คือรหัส:

int* a = 1; // pointer to 1st block of memory
*a = 5; // set the content of pointer to 5, but throws exception

person SHM    schedule 25.02.2016    source แหล่งที่มา
comment
คุณไม่สามารถเขียนลงในหน่วยความจำที่คุณไม่ได้เป็นเจ้าของได้ พื้นที่ที่อยู่บางส่วนถูกสงวนไว้ (ไม่ได้แมป)   -  person Mitch Wheat    schedule 25.02.2016
comment
ใครบอกว่าความทรงจำทั้งหมดของคุณเขียนได้? แล้วทำไมคุณถึงคิดว่ามันยังต่อเนื่องกันล่ะ?   -  person David Schwartz    schedule 25.02.2016
comment
every process receives a contiguous address space which is mapped to physical memory นี่เป็นเรื่องของระบบปฏิบัติการ ขึ้นอยู่กับการจัดการหน่วยความจำ following code in C which throws an exception นี่เป็นเรื่องของรหัส C มาตรฐาน C ไม่ทราบเกี่ยวกับระบบปฏิบัติการเฉพาะที่คุณอาจมีอยู่ในใจ และไม่สามารถระบุส่วนนั้นได้ เท่าที่มาตรฐาน C ดำเนินไป หน่วยความจำที่คุณไม่ได้รับมาด้วยวิธีมาตรฐาน C บางวิธี (เช่น malloc หรือการกำหนดตัวแปร) ไม่มีอยู่เพื่อวัตถุประสงค์ในทางปฏิบัติ และทำให้เกิด UB (พฤติกรรมที่ไม่ได้กำหนด) หากมีการเข้าถึง   -  person dxiv    schedule 25.02.2016


คำตอบ (2)


ทุกกระบวนการได้รับพื้นที่ที่อยู่ LOGICAL ที่ต่อเนื่องกัน ไม่ใช่พื้นที่ที่อยู่ติดกันเสมือน

หน้าแบบลอจิคัลถูกแมปกับเฟรมหน้าแบบฟิสิคัล

การแมปแบบลอจิคัลทำได้โดยใช้ PAGE TABLE ซึ่งมีการแมปจากเพจท้องถิ่นไปจนถึงเฟรมเพจ

อย่างไรก็ตาม ตารางหน้าอาจไม่มีการแมปกับกรอบหน้าสำหรับเพจลอจิคัลทุกหน้า

มีเหตุผลสองประการว่าทำไมสิ่งนี้ถึงเกิดขึ้น ขั้นแรก ระบบปฏิบัติการอาจไม่ (โดยปกติจะไม่) สร้างรายการตารางเพจที่ครอบคลุมพื้นที่ที่อยู่ทั้งหมด พารามิเตอร์ระบบหรือโควต้ากระบวนการอาจจำกัดขนาดของพื้นที่ที่อยู่แบบลอจิคัล บางระบบยังสงวนช่วงที่อยู่ไว้ว่าใช้งานไม่ได้

ประการที่สอง มีคนทำการแมปเพจแบบลอจิคัล นี่เป็นกระบวนการสองขั้นตอน (1) ใครบางคน (โดยปกติคือตัวโหลด) ต้องทำเครื่องหมายเพจลอจิคัลว่าถูกต้อง (2) ระบบปฏิบัติการต้องแมปเพจโลจิคัลกับเพจฟิสิคัล สิ่งนี้จะเกิดขึ้นเมื่อกระบวนการเข้าถึงเพจแบบลอจิคัลที่ถูกต้องซึ่งไม่มีการแม็ป ทำให้เกิดข้อบกพร่องของเพจ (นั่นคือหน่วยความจำเสมือน - การแมปเพจแบบลอจิคัลที่ถูกต้องใหม่แบบไดนามิกไปยังเฟรมหน้า)

รายการตารางหน้าสามารถมีได้สามสถานะ:

  1. มันไม่ถูกต้อง
  2. มันถูกต้องและแมปไปยังกรอบหน้าการแมป
  3. ถูกต้องแต่ไม่มีการแมปกับเฟรมเพจจริง (ขอย้ำอีกครั้ง หากมีการเข้าถึงรายการตารางเพจในสถานะนี้ จะทริกเกอร์ PAGE FAULT ที่ทำให้ระบบปฏิบัติการสร้างการแมปไปยังเฟรมเพจที่ถูกต้อง)

ในระหว่างรันไทม์ แอปพลิเคชันสามารถเรียกใช้บริการของระบบเพื่อทำให้เพจแบบลอจิคัลใช้ได้ในพื้นที่ที่อยู่แบบลอจิคัล

เพื่อเป็นการตรวจสอบความปลอดภัยเพื่อตรวจจับพอยน์เตอร์ที่หลงทาง ระบบส่วนใหญ่ (โดยปกติจะกำกับโดยตัวเชื่อมโยง) จะไม่แมปหน้าแรกเลย (อย่างไรก็ตาม แอปพลิเคชันมักจะสามารถแมปเพจผ่านการเรียกของระบบ) ของคุณ:

 int *a = 1 ;

ตั้งค่าที่อยู่ของ "a" ไปยังตำแหน่งที่จะอยู่ในหน้าแรกซึ่งไม่ถูกต้องเสมอไป

ของคุณ

*a = 5 ;

ทำให้โปรเซสเซอร์ (หน่วยการแปลหน่วยความจำ) เข้าถึงรายการตารางเพจสำหรับหน้าแรก ที่นั่น ตัวประมวลผลพบว่ารายการตารางหน้านี้ถูกทำเครื่องหมายว่าไม่ถูกต้อง (เช่น ไม่มีการแมปที่เป็นไปได้) ที่ทำให้เกิดการละเมิดการเข้าถึง

person user3344003    schedule 26.02.2016
comment
ที่อยู่แบบลอจิคัลไม่ใช่คำพ้องความหมายสำหรับที่อยู่เสมือนใช่ไหม ไม่งั้นก็ตอบได้ดี.. อาจจะดีกว่านี้ถ้าคุณพูดถึงความสัมพันธ์นี้กับการสลับหน้าไปยังดิสก์เมื่อหน่วยความจำกายภาพเหลือน้อย - person Joni; 27.02.2016
comment
ไม่ เสมือนและตรรกะเป็นสองสิ่งที่เกี่ยวข้องกัน แต่เป็นแนวคิดที่แตกต่างกัน - person user3344003; 27.02.2016

พื้นที่ที่อยู่ทั้งหมดไม่ได้แมปกับหน่วยความจำกายภาพ เพียงบางส่วนเท่านั้น คุณไม่สามารถใช้ที่อยู่ที่ไม่ได้แมปได้

โดยปกติแล้วพื้นที่ที่อยู่บางส่วนจะถูกสงวนไว้สำหรับระบบปฏิบัติการ บางส่วนของพื้นที่ที่อยู่อาจถูกแมปกับไฟล์ ส่วนอื่นๆ กับอุปกรณ์ฮาร์ดแวร์ แนวคิดทั้งหมดของการมีระบบหน่วยความจำ "เสมือน" คือคุณสามารถใช้พื้นที่ที่อยู่เดียวเพื่ออ้างถึงหลายสิ่งได้ ซึ่งหมายความว่าที่อยู่เสมือนไม่ใช่ทั้งหมดจะ "ถูกต้อง" ตลอดเวลา

person Joni    schedule 25.02.2016
comment
ส่วนไหนของมัน? คุณมีลิงค์สำหรับข้อมูลเพิ่มเติมไหม? - person SHM; 25.02.2016
comment
การค้นหาการแมปที่อยู่เป็นลักษณะเฉพาะของระบบปฏิบัติการ ตัวอย่างเช่นเคอร์เนล Linux เปิดเผยข้อมูลนี้ใน /proc/self/maps - person Joni; 25.02.2016