รหัสต่อไปนี้ทำให้ฉันมีข้อผิดพลาดในการแบ่งกลุ่มเมื่อทำงานบนเครื่อง 2Gb แต่ทำงานบนเครื่อง 4GB
int main()
{
int c[1000000];
cout << "done\n";
return 0;
}
ขนาดของอาร์เรย์เป็นเพียง 4Mb มีการ จำกัด ขนาดของอาร์เรย์ที่สามารถใช้ใน c ++ หรือไม่?
รหัสต่อไปนี้ทำให้ฉันมีข้อผิดพลาดในการแบ่งกลุ่มเมื่อทำงานบนเครื่อง 2Gb แต่ทำงานบนเครื่อง 4GB
int main()
{
int c[1000000];
cout << "done\n";
return 0;
}
ขนาดของอาร์เรย์เป็นเพียง 4Mb มีการ จำกัด ขนาดของอาร์เรย์ที่สามารถใช้ใน c ++ หรือไม่?
คำตอบ:
คุณอาจจะมีสแต็กล้นตรงนี้ อาร์เรย์ใหญ่เกินไปที่จะพอดีกับพื้นที่ที่อยู่สแต็กของโปรแกรมของคุณ
หากคุณจัดสรรอาร์เรย์บนฮีปคุณน่าจะใช้ได้โดยสมมติว่าเครื่องของคุณมีหน่วยความจำเพียงพอ
int* array = new int[1000000];
แต่จำไว้ว่าสิ่งนี้จะทำให้คุณต้องใช้delete[]
อาร์เรย์ ทางออกที่ดีกว่าคือใช้std::vector<int>
และปรับขนาดเป็น 1000000 องค์ประกอบ
ใน C หรือ C ++ โลคัลอ็อบเจ็กต์มักจะถูกจัดสรรบนสแต็ก คุณกำลังจัดสรรอาร์เรย์ขนาดใหญ่บนสแต็กเกินกว่าที่สแต็กจะจัดการได้ดังนั้นคุณจึงได้รับstackoverflow
อย่าจัดสรรในพื้นที่บนสแต็กให้ใช้ที่อื่นแทน นี้สามารถทำได้โดยการทำให้วัตถุที่ทั่วโลกหรือจัดสรรบนโลกกอง ตัวแปรส่วนกลางนั้นใช้ได้ถ้าคุณไม่ได้ใช้จากหน่วยคอมไพล์อื่น ๆ เพื่อให้แน่ใจว่าสิ่งนี้จะไม่เกิดขึ้นโดยบังเอิญให้เพิ่มตัวระบุหน่วยเก็บแบบคงที่หรือใช้ฮีป
สิ่งนี้จะจัดสรรในส่วน BSS ซึ่งเป็นส่วนหนึ่งของฮีป:
static int c[1000000];
int main()
{
cout << "done\n";
return 0;
}
สิ่งนี้จะจัดสรรในเซ็กเมนต์ DATA ซึ่งเป็นส่วนหนึ่งของฮีปด้วย:
int c[1000000] = {};
int main()
{
cout << "done\n";
return 0;
}
สิ่งนี้จะจัดสรรในตำแหน่งที่ไม่ระบุบางส่วนในฮีป:
int main()
{
int* c = new int[1000000];
cout << "done\n";
return 0;
}
delete
new
แต่ถ้าคุณแน่ใจว่าคุณจัดสรรหน่วยความจำเพียงครั้งเดียว (เช่นเดียวกับใน main) ก็ไม่จำเป็นอย่างยิ่ง - รับประกันว่าหน่วยความจำจะถูกปลดปล่อยเมื่อออกจาก main แม้จะไม่ชัดเจนdelete
ก็ตาม
นอกจากนี้หากคุณใช้งานในระบบ UNIX & Linux ส่วนใหญ่คุณสามารถเพิ่มขนาดสแต็กชั่วคราวโดยใช้คำสั่งต่อไปนี้:
ulimit -s unlimited
แต่ระวังหน่วยความจำเป็นทรัพยากรที่ จำกัด และด้วยพลังอันยิ่งใหญ่มาพร้อมกับความรับผิดชอบที่ยิ่งใหญ่ :)
อาร์เรย์ของคุณกำลังถูกจัดสรรบนสแต็กในกรณีนี้พยายามจัดสรรอาร์เรย์ที่มีขนาดเท่ากันโดยใช้การจัดสรร
เนื่องจากคุณเก็บอาร์เรย์ไว้ในสแต็ก คุณควรเก็บไว้ในกอง ดูลิงก์นี้เพื่อทำความเข้าใจแนวคิดของฮีปและสแตก