ลบ [] รู้ได้อย่างไรว่าเป็นอาร์เรย์


136

เอาล่ะฉันคิดว่าเราทุกคนยอมรับว่าสิ่งที่เกิดขึ้นกับรหัสต่อไปนี้ไม่ได้กำหนดขึ้นอยู่กับสิ่งที่ส่งผ่าน

void deleteForMe(int* pointer)
{
     delete[] pointer;
}

ตัวชี้อาจเป็นสิ่งที่แตกต่างกันได้ดังนั้นการดำเนินการอย่างไม่มีเงื่อนไขdelete[]จึงไม่ได้กำหนดไว้ อย่างไรก็ตามสมมติว่าเรากำลังส่งตัวชี้อาร์เรย์

int main()
{
     int* arr = new int[5];
     deleteForMe(arr);
     return 0;
}

คำถามของฉันคือในกรณีนี้ที่ตัวชี้เป็นอาร์เรย์ใครเป็นคนรู้เรื่องนี้ ฉันหมายถึงจากมุมมองของภาษา / คอมไพเลอร์ไม่มีความคิดว่าarrเป็นตัวชี้อาร์เรย์หรือไม่เมื่อเทียบกับตัวชี้ไปยัง int เดียว Heck ไม่รู้ด้วยซ้ำว่าarrถูกสร้างขึ้นแบบไดนามิกหรือไม่ แต่ถ้าฉันทำสิ่งต่อไปนี้แทน

int main()
{
     int* num = new int(1);
     deleteForMe(num);
     return 0;
}

ระบบปฏิบัติการมีความฉลาดพอที่จะลบเพียง int เดียวและไม่ใช้ 'ความสนุกสนานในการฆ่า' บางประเภทโดยการลบหน่วยความจำที่เหลือเกินกว่าจุดนั้น (ตรงกันข้ามกับสตริงที่strlenไม่มีการตัด\0ทอนและจะดำเนินต่อไปจนกว่าจะถึง ฮิต 0)

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



6
มันรู้จากวงเล็บเหลี่ยมหลังการลบ
JoelFan

"ตัวชี้คืออาร์เรย์" ไม่พอยน์เตอร์ไม่เคยเป็นอาร์เรย์ พวกเขามักชี้ไปที่องค์ประกอบแรกของอาร์เรย์ แต่นั่นเป็นสิ่งที่แตกต่าง
Aaron McDaid

คำตอบ:


100

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

คอมไพเลอร์จะต้องติดตามจำนวนวัตถุที่ต้องลบออกไป อาจทำได้โดยการจัดสรรมากเกินไปเพื่อจัดเก็บขนาดอาร์เรย์ สำหรับรายละเอียดเพิ่มเติมโปรดดูที่C ++ ซูเปอร์คำถามที่พบบ่อย


14
อันที่จริงการใช้ delete [] เพื่อลบสิ่งที่สร้างขึ้นใหม่นั้นมีประโยชน์ taossa.com/index.php/2007/01/03/…
Rodrigo

23
@Rodrigo ลิงก์ในความคิดเห็นของคุณเสีย แต่โชคดีที่เครื่อง wayback มีสำเนาอยู่ที่replay.web.archive.org/20080703153358/http://taossa.com/…
David Gardner

103

คำถามหนึ่งที่คำตอบที่ได้รับจนถึงตอนนี้ดูเหมือนจะไม่ได้อยู่: หากไลบรารีรันไทม์ (ไม่ใช่ระบบปฏิบัติการจริงๆ) สามารถติดตามจำนวนสิ่งต่างๆในอาร์เรย์ได้แล้วทำไมเราถึงต้องการdelete[]ไวยากรณ์ด้วยล่ะ? เหตุใดจึงไม่สามารถใช้deleteแบบฟอร์มเดียวเพื่อจัดการการลบทั้งหมดได้

คำตอบนี้ย้อนกลับไปที่รากของ C ++ ในฐานะภาษาที่เข้ากันได้กับ C (ซึ่งมันไม่ได้มุ่งมั่นที่จะเป็นอีกต่อไป) ปรัชญาของ Stroustrup คือโปรแกรมเมอร์ไม่ควรจ่ายเงินสำหรับคุณสมบัติใด ๆ ที่พวกเขาไม่ได้ใช้ หากพวกเขาไม่ได้ใช้อาร์เรย์ก็ไม่ควรต้องแบกรับต้นทุนของอาร์เรย์อ็อบเจ็กต์สำหรับหน่วยความจำที่จัดสรรทุกชิ้น

นั่นคือถ้ารหัสของคุณทำ

Foo* foo = new Foo;

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

เนื่องจากเฉพาะการจัดสรรอาร์เรย์เท่านั้นที่ถูกตั้งค่าให้มีข้อมูลขนาดอาร์เรย์พิเศษคุณจึงต้องบอกให้ไลบรารีรันไทม์ค้นหาข้อมูลนั้นเมื่อคุณลบอ็อบเจ็กต์ นั่นเป็นเหตุผลที่เราต้องใช้

delete[] bar;

แทนที่จะเป็นเพียง

delete bar;

ถ้า bar เป็นตัวชี้ไปยังอาร์เรย์

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


20
"ความวุ่นวายเกี่ยวกับหน่วยความจำที่เพิ่มขึ้นสองสามไบต์ดูเหมือนจะแปลกตาในทุกวันนี้" โชคดีสำหรับคนเช่นนี้อาร์เรย์เปล่าก็เริ่มดูแปลกตาเช่นกันดังนั้นพวกเขาสามารถใช้เวกเตอร์หรือบูสต์ :: อาร์เรย์และลืมลบ [] ตลอดไป :-)
Steve Jessop

28

ใช่ระบบปฏิบัติการจะเก็บบางสิ่งไว้ใน "พื้นหลัง" ตัวอย่างเช่นหากคุณเรียกใช้

int* num = new int[5];

ระบบปฏิบัติการสามารถจัดสรร 4 ไบต์พิเศษจัดเก็บขนาดของการจัดสรรใน 4 ไบต์แรกของหน่วยความจำที่จัดสรรและส่งคืนตัวชี้ออฟเซ็ต (กล่าวคือจัดสรรพื้นที่หน่วยความจำ 1,000 ถึง 1024 แต่ตัวชี้กลับชี้ไปที่ 1004 โดยมีตำแหน่ง 1000- 1003 จัดเก็บขนาดของการจัดสรร) จากนั้นเมื่อมีการเรียกลบมันสามารถดู 4 ไบต์ก่อนที่ตัวชี้จะส่งผ่านไปเพื่อค้นหาขนาดของการจัดสรร

ฉันแน่ใจว่ามีวิธีอื่นในการติดตามขนาดของการจัดสรร แต่นั่นเป็นทางเลือกหนึ่ง


26
+1 - จุดที่ถูกต้องโดยทั่วไปยกเว้นว่าโดยปกติแล้วรันไทม์ของภาษาจะรับผิดชอบในการจัดเก็บข้อมูลเมตานี้ไม่ใช่ระบบปฏิบัติการ
sharptooth

จะเกิดอะไรขึ้นกับขนาดของอาร์เรย์หรือขนาดของวัตถุที่มีการกำหนดอาร์เรย์ไว้ มันแสดง 4 ไบต์เพิ่มเติมเมื่อคุณทำขนาดบนวัตถุนั้นหรือไม่?
Shree

3
ไม่ sizeof แสดงเพียงขนาดของอาร์เรย์ หากรันไทม์เลือกที่จะใช้งานโดยใช้วิธีการที่ฉันอธิบายไว้นั่นคือรายละเอียดการใช้งานอย่างเคร่งครัดและจากมุมมองของผู้ใช้ที่ควรมาสก์ หน่วยความจำก่อนตัวชี้ไม่ได้ 'เป็นของ' ของผู้ใช้และจะไม่ถูกนับ
bsdfish

2
ที่สำคัญกว่านั้น sizeof จะไม่ส่งกลับขนาดที่แท้จริงของอาร์เรย์ที่จัดสรรแบบไดนามิกไม่ว่าในกรณีใด ๆ สามารถส่งคืนขนาดที่ทราบในเวลาคอมไพล์เท่านั้น
bdonlan

เป็นไปได้ไหมที่จะใช้ข้อมูลเมตานี้ใน for loop เพื่อวนซ้ำอย่างถูกต้องเหนืออาร์เรย์ เช่น for(int i = 0; i < *(arrayPointer - 1); i++){ }
Sam

13

คำถามนี้คล้ายกับคำถามนี้มากและมีรายละเอียดมากมายที่คุณกำลังมองหา

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

สิ่งนี้สามารถดูได้ในการใช้งานบางอย่างโดยเรียกใช้โค้ดต่อไปนี้

int* pArray = new int[5];
int size = *(pArray-1);

จะได้ผลไหม ใน windows & linux เราไม่ได้ทำงานนี้
บัดดี้

1
ลองsize_t size = *(reinterpret_cast<size_t *>(pArray) - 1)แทน

9

deleteหรือdelete[]อาจจะเป็นอิสระทั้งสองหน่วยความจำที่จัดสรร (หน่วยความจำชี้) แต่ความแตกต่างใหญ่คือdeleteในอาร์เรย์จะไม่เรียกตัวทำลายของแต่ละองค์ประกอบของอาร์เรย์

อย่างไรก็ตามการผสมnew/new[]และdelete/delete[]น่าจะเป็น UB


1
คำตอบที่ชัดเจนสั้นและมีประโยชน์ที่สุด!
GntS


5

ฉันมีคำถามคล้าย ๆ กันนี้ ใน C คุณจัดสรรหน่วยความจำด้วย malloc () (หรือฟังก์ชันอื่นที่คล้ายกัน) และลบด้วย free () มี malloc () เพียงตัวเดียวซึ่งจัดสรรจำนวนไบต์ที่แน่นอน มีเพียงตัวเดียวฟรี () ซึ่งใช้ตัวชี้เป็นพารามิเตอร์

เหตุใดใน C คุณจึงสามารถส่งตัวชี้ให้เป็นอิสระได้ แต่ใน C ++ คุณต้องบอกว่าเป็นอาร์เรย์หรือตัวแปรเดียว

คำตอบที่ฉันได้เรียนรู้เกี่ยวข้องกับผู้ทำลายชั้นเรียน

หากคุณจัดสรรอินสแตนซ์ของคลาส MyClass ...

classes = new MyClass[3];

และลบด้วยการลบคุณอาจได้รับตัวทำลายสำหรับอินสแตนซ์แรกของ MyClass ที่เรียกเท่านั้น หากคุณใช้ลบ [] คุณสามารถมั่นใจได้ว่าตัวทำลายจะถูกเรียกสำหรับอินสแตนซ์ทั้งหมดในอาร์เรย์

นี่คือความแตกต่างที่สำคัญ หากคุณใช้งานประเภทมาตรฐาน (เช่น int) คุณจะไม่เห็นปัญหานี้จริงๆ นอกจากนี้คุณควรจำไว้ว่าพฤติกรรมในการใช้ลบบน [] ใหม่และลบ [] ใหม่นั้นไม่ได้กำหนดไว้ซึ่งอาจไม่ได้ผลเหมือนกันในทุกคอมไพเลอร์ / ระบบ


3

มันขึ้นอยู่กับรันไทม์ซึ่งรับผิดชอบการจัดสรรหน่วยความจำในลักษณะเดียวกับที่คุณสามารถลบอาร์เรย์ที่สร้างด้วย malloc ในมาตรฐาน C โดยใช้ฟรี ฉันคิดว่าแต่ละคอมไพเลอร์ใช้มันแตกต่างกัน วิธีหนึ่งโดยทั่วไปคือการจัดสรรเซลล์พิเศษสำหรับขนาดอาร์เรย์

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


3

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

ตัวอย่างวิธีการทำได้: ที่นี่

int* i = new int[4];

คอมไพเลอร์จะจัดสรร sizeof (int) * 5 ไบต์

int *temp = malloc(sizeof(int)*5)

จะจัดเก็บ4เป็นsizeof(int)ไบต์แรก

*temp = 4;

และตั้งค่า i

i = temp + 1;

ดังนั้นiชี้ไปที่อาร์เรย์ของ 4 องค์ประกอบไม่ใช่ 5

และ

delete[] i;

จะได้รับการดำเนินการดังต่อไปนี้

int *temp = i - 1;
int numbers_of_element = *temp; // = 4
... call destructor for numbers_of_element elements if needed
... that are stored in temp + 1, temp + 2, ... temp + 4
free (temp)

1

ตามความหมายตัวดำเนินการลบทั้งสองเวอร์ชันใน C ++ สามารถ "กิน" ตัวชี้ใดก็ได้ อย่างไรก็ตามหากมีการกำหนดตัวชี้ไปยังวัตถุชิ้นเดียวdelete[] UB จะส่งผลให้หมายความว่ามีอะไรเกิดขึ้นรวมถึงระบบขัดข้องหรือไม่มีอะไรเลย

C ++ ต้องการให้โปรแกรมเมอร์เลือกเวอร์ชันที่เหมาะสมของตัวดำเนินการลบโดยขึ้นอยู่กับเรื่องของ deallocation: array หรือ single object

หากคอมไพลเลอร์สามารถระบุได้โดยอัตโนมัติว่าตัวชี้ที่ส่งไปยังตัวดำเนินการลบเป็นอาร์เรย์ตัวชี้หรือไม่ก็จะมีตัวดำเนินการลบเพียงตัวเดียวใน C ++ ซึ่งจะเพียงพอสำหรับทั้งสองกรณี


1

ยอมรับว่าคอมไพเลอร์ไม่รู้ว่าเป็นอาร์เรย์หรือไม่ มันขึ้นอยู่กับโปรแกรมเมอร์

บางครั้งคอมไพเลอร์จะติดตามจำนวนวัตถุที่ต้องลบโดยจัดสรรมากเกินไปเพียงพอที่จะจัดเก็บขนาดอาร์เรย์ แต่ไม่จำเป็นเสมอไป

สำหรับข้อมูลจำเพาะที่สมบูรณ์เมื่อมีการจัดสรรพื้นที่เก็บข้อมูลเพิ่มเติมโปรดดู C ++ ABI (วิธีการใช้งานคอมไพเลอร์): Itanium C ++ ABI: Array Operator new Cookies


ฉันเพียงต้องการทุกคอมไพเลอร์ตั้งข้อสังเกตบางเอกสาร ABI สำหรับ C ++ +1 สำหรับลิงก์ที่ฉันเคยเยี่ยมชมมาก่อน ขอบคุณ.
Don Wakefield

0

คุณไม่สามารถใช้ลบสำหรับอาร์เรย์และคุณไม่สามารถใช้ลบ []สำหรับที่ไม่ใช่อาร์เรย์


8
ฉันคิดว่าคุณไม่ควรเพราะคอมไพเลอร์เฉลี่ยของคุณจะไม่ตรวจพบการละเมิด
Don Wakefield

0

"พฤติกรรมที่ไม่ได้กำหนด" ก็หมายความว่าข้อมูลจำเพาะของภาษาทำให้ไม่มีผู้รู้ว่าจะเกิดอะไรขึ้น มันไม่ได้หมายความว่าจะมีสิ่งเลวร้ายเกิดขึ้น

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

โดยทั่วไปจะมีสองชั้นที่นี่ ตัวจัดการหน่วยความจำพื้นฐานและการใช้งาน C ++

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

โดยทั่วไปการใช้งาน C ++ จะจดจำขนาดของอาร์เรย์หากจำเป็นต้องทำเพื่อจุดประสงค์ของตัวเองโดยทั่วไปเนื่องจากประเภทนี้มีตัวทำลายที่ไม่เป็นคู่แข่ง

ดังนั้นสำหรับประเภทที่มีตัวทำลายเล็กน้อยการใช้ "ลบ" และ "ลบ []" มักจะเหมือนกัน การใช้งาน C ++ เพียงแค่ส่งตัวชี้ไปยังตัวจัดการหน่วยความจำที่อยู่เบื้องหลัง สิ่งที่ต้องการ

free(p)

ในทางกลับกันสำหรับประเภทที่มีตัวทำลายที่ไม่สำคัญ "ลบ" และ "ลบ []" มีแนวโน้มที่จะแตกต่างกัน "ลบ" จะเป็นเช่นนั้น (โดยที่ T คือประเภทที่ตัวชี้ชี้ไป)

p->~T();
free(p);

ในขณะที่ "ลบ []" จะเป็นอย่างไร

size_t * pcount = ((size_t *)p)-1;
size_t count = *count;
for (size_t i=0;i<count;i++) {
  p[i].~T();
}
char * pmemblock = ((char *)p) - max(sizeof(size_t),alignof(T));
free(pmemblock);

-1

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

// overloaded new expression 
void* operator new[]( size_t size )
{
    // allocate 4 bytes more see comment below 
    int* ptr = (int*)malloc( size + 4 );

    // set value stored at address to 0 
    // and shift pointer by 4 bytes to avoid situation that
    // might arise where two memory blocks 
    // are adjacent and non-zero
    *ptr = 0;
    ++ptr; 

    return ptr;
}
//////////////////////////////////////////

// overloaded delete expression 
void static operator delete[]( void* ptr )
{
    // decrement value of pointer to get the
    // "Real Pointer Value"
    int* realPtr = (int*)ptr;
    --realPtr;

    free( realPtr );
}
//////////////////////////////////////////

// Template used to call destructor if needed 
// and call appropriate delete 
template<class T>
void Deallocate( T* ptr )
{
    int* instanceCount = (int*)ptr;
    --instanceCount;

    if(*instanceCount > 0) // if larger than 0 array is being deleted
    {
        // call destructor for each object
        for(int i = 0; i < *instanceCount; i++)
        {
            ptr[i].~T();
        }
        // call delete passing instance count witch points
        // to begin of array memory 
        ::operator delete[]( instanceCount );
    }
    else
    {
        // single instance deleted call destructor
        // and delete passing ptr
        ptr->~T();
        ::operator delete[]( ptr );
    }
}

// Replace calls to new and delete
#define MyNew ::new
#define MyDelete(ptr) Deallocate(ptr)

// structure with constructor/ destructor
struct StructureOne
{
    StructureOne():
    someInt(0)
    {}
    ~StructureOne() 
    {
        someInt = 0;
    }

    int someInt;
};
//////////////////////////////

// structure without constructor/ destructor
struct StructureTwo
{
    int someInt;
};
//////////////////////////////


void main(void)
{
    const unsigned int numElements = 30;

    StructureOne* structOne = nullptr;
    StructureTwo* structTwo = nullptr;
    int* basicType = nullptr;
    size_t ArraySize = 0;

/**********************************************************************/
    // basic type array 

    // place break point here and in new expression
    // check size and compare it with size passed 
    // in to new expression size will be the same
    ArraySize = sizeof( int ) * numElements;

    // this will be treated as size rather than object array as there is no 
    // constructor and destructor. value assigned to basicType pointer
    // will be the same as value of "++ptr" in new expression
    basicType = MyNew int[numElements];

    // Place break point in template function to see the behavior
    // destructors will not be called and it will be treated as 
    // single instance of size equal to "sizeof( int ) * numElements"
    MyDelete( basicType );

/**********************************************************************/
    // structure without constructor and destructor array 

    // behavior will be the same as with basic type 

    // place break point here and in new expression
    // check size and compare it with size passed 
    // in to new expression size will be the same
    ArraySize = sizeof( StructureTwo ) * numElements;

    // this will be treated as size rather than object array as there is no 
    // constructor and destructor value assigned to structTwo pointer
    // will be the same as value of "++ptr" in new expression
    structTwo = MyNew StructureTwo[numElements]; 

    // Place break point in template function to see the behavior
    // destructors will not be called and it will be treated as 
    // single instance of size equal to "sizeof( StructureTwo ) * numElements"
    MyDelete( structTwo );

/**********************************************************************/
    // structure with constructor and destructor array 

    // place break point check size and compare it with size passed in
    // new expression size in expression will be larger by 4 bytes
    ArraySize = sizeof( StructureOne ) * numElements;

    // value assigned to "structOne pointer" will be different 
    // of "++ptr" in new expression  "shifted by another 4 bytes"
    structOne = MyNew StructureOne[numElements];

    // Place break point in template function to see the behavior
    // destructors will be called for each array object 
    MyDelete( structOne );
}
///////////////////////////////////////////

-2

เพียงกำหนดตัวทำลายภายในคลาสและรันโค้ดของคุณด้วยไวยากรณ์ทั้งสอง

delete pointer

delete [] pointer

ตามผลลัพธ์คุณสามารถหาแนวทางแก้ไขได้


ใช้ลบ [] เมื่อคุณสร้างประเภทอาร์เรย์ใหม่ ตัวอย่างเช่น int * a = int ใหม่; int * b = int ใหม่ [5]; ลบ; ลบ [] b;
Lineesh K Mohan

-3

คำตอบ:

int * pArray = int ใหม่ [5];

ขนาด int = * (pArray-1);

โพสต์ด้านบนไม่ถูกต้องและสร้างค่าที่ไม่ถูกต้อง "-1" นับองค์ประกอบบน Windows OS 64 บิตขนาดบัฟเฟอร์ที่ถูกต้องอยู่ในที่อยู่ Ptr - 4 ไบต์

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