คุณสมบัติของตัวชี้ไปยังอาร์เรย์ความยาวเป็นศูนย์


21

พิจารณา

int main()
{
    auto a = new int[0];
    delete[] a; // So there's no memory leak
}

ระหว่างการคัดลอกเริ่มต้นและการลบคุณได้รับอนุญาตให้อ่านตัวชี้ที่a + 1?

นอกจากนี้ไม่อนุญาตให้มีภาษาคอมไพเลอร์ชุดaไปnullptr?


2
@Fareanor: คุณสามารถอ่านได้aอย่างแน่นอน (แน่นอนคุณไม่สามารถตรวจสอบได้)
Bathsheba

8
@RasmiRanjanNayak: นั่นคือฮอกวอช
Bathsheba

2
@RasmiRanjanNayak โอ้ฉัน ... ไม่
Ted Lyngmo

1
@TedLyngmo: เมื่อฉันพูดว่า "อ่านตัวชี้ที่a + 1" เป็นauto b = a + 1;พฤติกรรมที่ไม่ได้กำหนดรหัสต่อไปนี้หรือไม่ (ฉันคิดว่ามันคือ).
Bathsheba

2
@ Ayxan ฉันเดาในกรณีที่0เป็นจริงผลลัพธ์ของการแสดงออกบางอย่างที่คุณไม่ทราบจนกว่ารันไทม์ เนื่องจากnew int[0]มีความปลอดภัยจึงช่วยให้คุณไม่ต้องกังวลเกี่ยวกับการแยกย่อย / กรณีพิเศษ ลองนึกภาพถ้าผมจะเริ่มต้นกับstd::vector std::vector<int> v(0);
scohe001

คำตอบ:


3
    auto a = new int[0];

ตาม[basic.compound.3]ค่าที่เก็บไว้aจะต้องเป็นหนึ่งในค่าต่อไปนี้:

  1. ตัวชี้ไปยังวัตถุ (ชนิดint)
  2. ตัวชี้ผ่านจุดสิ้นสุดของวัตถุ
  3. โมฆะ
  4. โมฆะ

เราสามารถแยกความเป็นไปได้แรกออกเนื่องจากไม่มีวัตถุประเภทที่intสร้างขึ้น ความเป็นไปได้ที่สามถูกตัดออกเนื่องจาก C ++ ต้องการตัวชี้ที่ไม่ใช่ค่า null ที่จะถูกส่งคืน (ดู[basic.stc.dynamic.allocation.2] ) ดังนั้นเราจึงมีความเป็นไปได้สองอย่าง: ตัวชี้ผ่านจุดสิ้นสุดของวัตถุหรือตัวชี้ที่ไม่ถูกต้อง

ฉันอยากจะเห็นaว่าเป็นตัวชี้อดีตที่ผ่านมา แต่ฉันไม่ได้มีการอ้างอิงที่มีชื่อเสียงในการสร้างที่แน่นอน (แม้ว่าจะมีความหมายที่ชัดเจนของเรื่องนี้ใน[basic.stc]โดยดูว่าคุณสามารถใช้deleteตัวชี้นี้ได้อย่างไร) ดังนั้นฉันจะสร้างความบันเทิงที่เป็นไปได้ทั้งสองอย่างในคำตอบนี้

ระหว่างการคัดลอกเริ่มต้นและการลบคุณได้รับอนุญาตให้อ่านตัวชี้ที่a + 1?

พฤติกรรมไม่ได้กำหนดไว้ตามที่กำหนดโดย[expr.add.4]โดยไม่คำนึงถึงความเป็นไปได้ที่จะใช้จากด้านบน

ถ้าaเป็นพอยน์เตอร์ตัวสุดท้ายจะถูกพิจารณาให้ชี้ไปที่องค์ประกอบสมมุติที่ดัชนี0ของอาร์เรย์ที่ไม่มีองค์ประกอบ การเพิ่มจำนวนเต็มjจะaถูกกำหนดเฉพาะเมื่อ0≤0+j≤nซึ่งnขนาดของอาเรย์ ในกรณีของเราnเป็นศูนย์ดังนั้นจำนวนเงินa+jที่ถูกกำหนดให้เฉพาะเมื่อเป็นj 0โดยเฉพาะอย่างยิ่งการเพิ่ม1ไม่ได้กำหนด

หากaไม่ถูกต้องเราจะตกลงไปที่ "มิฉะนั้นพฤติกรรมจะไม่ได้กำหนด" (ไม่น่าแปลกใจกรณีที่กำหนดครอบคลุมเฉพาะค่าตัวชี้ที่ถูกต้องเท่านั้น)

นอกจากนี้ไม่อนุญาตให้มีภาษาคอมไพเลอร์ชุดaไปnullptr?

เลขจากดังกล่าวข้างต้น[basic.stc.dynamic.allocation.2] : "หากคำขอสำเร็จค่าส่งกลับโดยฟังก์ชั่นการจัดสรรถอดเปลี่ยนเป็นค่าตัวชี้ null ไม่ใช่" นอกจากนี้ยังมีเชิงอรรถเรียกออกว่า C ++ (แต่ไม่ใช่ C) ต้องใช้ตัวชี้ที่ไม่เป็นโมฆะในการตอบสนองต่อการร้องขอเป็นศูนย์


1
หากเป็นค่าตัวชี้ที่ไม่ถูกต้องคุณจะมีปัญหาร้ายแรงจากeel.is/c++draft/basic.stc#4
TC

@TC True ซึ่งมีความหมายอย่างยิ่งว่าไม่สามารถเป็นค่าตัวชี้ที่ไม่ถูกต้อง
JaMiT

23

ต่อล่าสุดอภิปรายสะท้อน CWG เป็นผลมาจากปัญหาบรรณาธิการ 3178 , new int[0]ผลิตสิ่งที่กำลังจะเรียกว่า"ที่ผ่านมาที่สิ้นสุด" ค่าตัวชี้

มันตามที่aไม่สามารถเป็นโมฆะและa + 1จะไม่ได้กำหนดโดย[expr.add] / 4


4
"ตามการอภิปรายตัวสะท้อนแสง CWG ล่าสุดอันเป็นผลมาจากปัญหาบรรณาธิการ 3178 new int[0]สร้างสิ่งที่เรียกว่า" ตัวชี้ "ในอดีต" ค่าปัจจุบัน "นี้ไม่ถูกต้อง ไม่มีการอภิปรายกันมากนัก บุคคลหนึ่งแนะนำว่าค่าควรเป็น "ตัวชี้ผ่านจุดสิ้นสุดของวัตถุ" และคำสั่งนี้ถูกตั้งคำถามเพราะในกรณีของอาร์เรย์ที่มี0องค์ประกอบไม่มีวัตถุที่จะผ่านจุดสิ้นสุดของวัตถุ
ทนายความภาษา

@LanguageLawyer ดูเหมือนว่าจะไม่มีข้อสงสัยa + 1ใด ๆ ที่ไม่ได้กำหนดไว้ดังนั้นประเด็นของคุณเกี่ยวข้องกับการaเป็นโมฆะหรือเปล่า?
MM

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

@MM ฉันคิดว่าไม่ได้a + 1กำหนดและอาจจะมีค่าตัวชี้ผลลัพธ์ที่เกิดขึ้นจะถูกเรียกว่า "ตัวชี้ผ่านจุดสิ้นสุด" ฉันไม่ได้บอกว่าคำตอบนั้นผิด มันไม่ถูกต้องเล็กน้อยเนื่องจากสามารถเข้าใจได้เนื่องจากมีการพูดคุยกันเป็นระยะเวลานานกับฉันทามติที่เพิ่งระบุว่าผลลัพธ์คือ "ตัวชี้ผ่านจุดสิ้นสุด" นั้นเพียงพอที่จะแก้ไขปัญหาได้ ปัญหาของ "ตัวชี้ผ่านจุดสิ้นสุด" คือมันผ่านจุดสิ้นสุดของวัตถุบางอย่างและการลบออก1จากค่าตัวชี้จะให้ตัวชี้หนึ่งไปยังวัตถุซึ่งอาจไม่ควรเป็นกรณีสำหรับอาร์เรย์ของ0องค์ประกอบ
นักกฎหมายด้านภาษา

2
@Bathsheba คุณคิดว่าอาจมีอะไรเพิ่มเติมเกี่ยวกับถ้อยคำที่มีข้อบกพร่องหรือไม่
นักกฎหมายด้านภาษา
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.