সি ++ এ সর্বাধিক অ্যারে দৈর্ঘ্যের সীমা কি আছে?


181

C ++ এ অ্যারের জন্য সর্বোচ্চ দৈর্ঘ্য কি আছে?

এটি কি সি ++ সীমা বা এটি আমার মেশিনের উপর নির্ভর করে? এটি কি তাত্পর্যযোগ্য? এটি অ্যারে তৈরির ধরণের উপর নির্ভর করে?

আমি কি এই সীমাটি কোনওভাবে ভাঙ্গতে পারি বা তথ্য সংরক্ষণের আরও ভাল উপায়ের জন্য আমাকে অনুসন্ধান করতে হবে? এবং সহজ উপায় কি হওয়া উচিত?

আমাকে যা করতে হবে তা হ'ল একটি অ্যারেতে দীর্ঘ দীর্ঘতর সঞ্চয় করা, আমি একটি লিনাক্স পরিবেশে কাজ করছি। আমার প্রশ্ন: আমার যদি এন> 10 সংখ্যার সাথে দীর্ঘ দীর্ঘ ইন্টিজারের একটি অ্যারে সঞ্চয় করতে হয় তবে আমার কী করতে হবে?

আমার এটি দরকার কারণ আমি স্কুলের জন্য কিছু ক্রিপ্টোগ্রাফিক অ্যালগরিদম (উদাহরণস্বরূপ পি-পোলার্ড) লিখছি, এবং পূর্ণসংখ্যার প্রাচীর এবং অ্যারে উপস্থাপনের দৈর্ঘ্যটিতে এটি আঘাত করেছি।

উত্তর:


163

দুটি সীমা রয়েছে, উভয়ই সি ++ দ্বারা প্রয়োগ করা হয় না বরং হার্ডওয়ার দ্বারা প্রয়োগ করা হয়।

প্রথম সীমাটি (কখনই পৌঁছানো উচিত নয়) অ্যারেতে (এবং এর আকার) সূচক বর্ণনা করার জন্য ব্যবহৃত আকারের সীমাবদ্ধতার দ্বারা সেট করা হয়। এটি সিস্টেমের std::size_tনিতে পারে সর্বোচ্চ মূল্য দ্বারা দেওয়া হয় । এই তথ্য টাইপটি কোনও বস্তুর বাইটে আকার ধারণ করতে যথেষ্ট বড়

অন্য সীমাটি একটি শারীরিক স্মৃতি সীমা। অ্যারেতে আপনার অবজেক্টগুলি বৃহত্তর হয়, মেমরি পূর্ণ হওয়ার কারণে এই সীমাটি যত তাড়াতাড়ি পৌঁছে যায়। উদাহরণস্বরূপ, vector<int>প্রদত্ত আকারের n এর একটি সাধারণত ধরণের ধরণের অ্যারে vector<char>(মাইনাস একটি ছোট ধ্রুবক মান) এর intচেয়ে বহুগুণ বেশি সময় নেয় , যেহেতু সাধারণত তার চেয়ে বড় char। অতএব, মেমরি পূর্ণ হওয়ার আগে vector<char>একটিতে আরও আইটেম থাকতে পারে vector<int>। কাঁচা সি-স্টাইলের অ্যারেগুলির জন্য একই গণনা int[]এবং char[]

অধিকন্তু, এই উচ্চতর সীমাটি allocatorনির্মাণের জন্য ব্যবহৃত ধরণের দ্বারা প্রভাবিত হতে পারে vectorকারণ allocatorম্যানিটি যেভাবে চায় পরিচালনা করতে পারে free একটি খুব বিজোড় তবে তবুও অনুমেয়যোগ্য বরাদ্দকারী মেমরিটিকে এমনভাবে পল করতে পারে যে কোনও অবজেক্টের শেয়ারের সংস্থানগুলির অভিন্ন উদাহরণ। এইভাবে, আপনি একটি ধারকটিতে প্রচুর অভিন্ন জিনিস inোকাতে পারেন যা অন্যথায় সমস্ত উপলব্ধ মেমরি ব্যবহার করে।

তা ছাড়া, সি ++ কোনও সীমাবদ্ধতা প্রয়োগ করে না।


20
এছাড়াও আপনি সাধারণত স্ট্যাকের আকারের সীমাটি সহজেই হিট করতে পারেন, বিশেষত যদি আবার থ্রেড ব্যবহার করে যা বাস্তবায়ন নির্দিষ্ট (তবে পরিবর্তিত হতে সক্ষম) হয়।
আলারিক

@ অ্যালারিক: সত্য। আমি সিস্টেমের স্পেসিফিকেশনে খুব বেশি গভীরভাবে যেতে চাইনি কারণ সেগুলির মধ্যে অনেক বেশি পার্থক্য রয়েছে এবং আমি তাদের কোনওটিতেই বিশেষজ্ঞ নই।
কনরাড রুডল্ফ

@ কনরাড, বরাদ্দকারীর ধরণের সম্পর্কে আকর্ষণীয় বিষয় এবং এমন কিছু নয় যা আমি অবগত ছিলাম। তথ্যের জন্য ধন্যবাদ।
স্মাকএল

11
std :: আকার_t সাধারণত (সর্বদা?) পয়েন্টারের আকার হয় না, সবচেয়ে বড় পূর্ণসংখ্যার আকার না হয় যার পূর্ণসংখ্যার গণিত ইউনিটে দেশীয় হার্ডওয়্যার সমর্থন রয়েছে। প্রতিটি x86 ওএসে আমি ব্যবহার করেছি, আকার_টি 32-বিট ওএসের জন্য 32-বিট এবং 64-বিট ওএসের জন্য 64-বিট is
মিঃ ফুজ

2
আমার বোধগম্যতা হল একটি অ্যারের সর্বোচ্চ সীমাটি প্রসেসরের শব্দের সর্বাধিক মান । এটি ইনডেক্সিং অপারেটরের কারণে। উদাহরণস্বরূপ, একটি মেশিনের শব্দের আকার 16 বিট হতে পারে তবে 32 বিটের একটি ঠিকানা নিবন্ধ থাকতে পারে। মেমরির একটি অংশ প্যারামিটার দ্বারা newবা পাস করার মাধ্যমে আকারে সীমিত malloc। অ্যারের চেয়ে বড় মেমরির এক অংশ পয়েন্টারের মাধ্যমে অ্যাক্সেস করা যায়।
থমাস ম্যাথিউজ

171

স্ট্যাক ফ্রেমের আকারের সীমাটি কেউ উল্লেখ করেনি ।

দুটি স্থানে মেমরি বরাদ্দ করা যেতে পারে:

  • গাদা (গতিশীল বরাদ্দ মেমরি) এ।
    আকারের সীমাটি হ'ল অপ্রয়োজনীয় ডেটা ( অর্থাত্ হার্ডডিস্কে পৃষ্ঠাগুলি সরাতে) অস্থায়ীভাবে সঞ্চয় করতে অন্যান্য ডিভাইসগুলি ব্যবহার করে উপলব্ধ হার্ডওয়্যার এবং ওএসের স্থান অনুকরণের ক্ষমতার সংমিশ্রণ ।
  • স্ট্যাকের (স্থানীয়ভাবে ঘোষিত ভেরিয়েবল)।
    আকারের সীমাটি সংকলক সংজ্ঞায়িত (সম্ভাব্য হার্ডওয়্যার সীমা সহ)। আপনি যদি সংকলক ডকুমেন্টেশন পড়ে থাকেন তবে আপনি প্রায়শই এই আকারটিকে টুইঙ্ক করতে পারেন।

সুতরাং আপনি যদি গতিশীলভাবে একটি অ্যারে বরাদ্দ করেন (সীমাটি বড় এবং অন্যান্য পোস্টগুলির দ্বারা বিশদে বর্ণিত হয়)।

int* a1 = new int[SIZE];  // SIZE limited only by OS/Hardware

বিকল্পভাবে যদি অ্যারেটি স্ট্যাকের জন্য বরাদ্দ করা হয় তবে আপনি স্ট্যাক ফ্রেমের আকারের দ্বারা সীমাবদ্ধ। এনবি ভেক্টর এবং অন্যান্য পাত্রে স্ট্যাকের একটি ছোট উপস্থিতি রয়েছে তবে সাধারণত প্রচুর পরিমাণে ডেটা হিটে থাকে।

int a2[SIZE]; // SIZE limited by COMPILER to the size of the stack frame

4
বড় অ্যারেগুলির পছন্দের বরাদ্দ কোনও স্ট্যাক বা বিশ্বব্যাপী সংজ্ঞায়িত নয় বরং গতিশীল বরাদ্দের মাধ্যমে ( newবা মাধ্যমে malloc) হয়।
থমাস ম্যাথিউস

1
@ থমাস ম্যাথিউস: আমার পৃথিবীতে নেই। গতিশীল বরাদ্দ হওয়া অবজেক্টগুলির পরিচালনা প্রয়োজন require যদি এটি গতিশীলভাবে বরাদ্দের প্রয়োজন হয় তবে আমি স্ট্যাক অবজেক্টটি ব্যবহার করব যা স্ট্যান্ড :: ভেক্টরের মতো গতিশীল বরাদ্দকৃত স্মৃতিগুলিকে উপস্থাপন করে।
মার্টিন ইয়র্ক

2
একটি কর্নার কেস হারিয়েছে: Global Arraysযদিও কোনও সৌন্দর্য নয় এবং সর্বোত্তমভাবে এড়ানো যায়, এগুলি সীমাবদ্ধতার আওতায় পড়ে না stackএবং আপনার প্রয়োজন নেই malloc/ freeতাদের সাথে কাজ করার দরকার নেই।
টেড

1
@ted, কেন বিশ্বব্যাপী অ্যারেগুলি "সেরা এড়ানো" হবে? আরও সুনির্দিষ্ট হওয়ার জন্য আমি মনে করি আপনি স্থিরভাবে বরাদ্দ করা অ্যারেগুলি বোঝাচ্ছেন। তাদের সুযোগ বিশ্বব্যাপী হতে হবে না। আমি যুক্তি দেব যে তারা ডায়নামিক অ্যারেগুলির চেয়ে আরও ভাল কারণ আপনি তাদের সাথে নিখুঁত ঠিকানা ব্যবহার করতে পারেন (কমপক্ষে লিনাক্সে) যা আপনি গতিশীলভাবে বরাদ্দ করা অ্যারেগুলি করতে পারেন না।
জেড বোসন

2
খুব গুরুত্বপূর্ণ বিষয়। আমি সম্প্রতি একটি "উত্পাদন-মানের" ওপেন-সোর্স প্রকল্প জুড়ে এসেছি যা একটি কনফিগারযোগ্য সর্বোচ্চ-বাফার আকার সরবরাহ করে। সমস্ত বাফারগুলি স্ট্যাকের জন্য বরাদ্দ করা হয়েছিল, সুতরাং একটি বৃহত পরিমাণের মান কনফিগার করার ফলে প্রোগ্রামটি তত্ক্ষণাত লঞ্চের সময় সেগফ্ল্টের কারণ হয়ে উঠবে।
আরথ

13

তাত্ত্বিক অবস্থানের চেয়ে ব্যবহারিক দিক থেকে এটিকে দেখার জন্য, 32 বিট উইন্ডোজ সিস্টেমে, একক প্রক্রিয়ার জন্য সর্বোচ্চ মোট মেমরির পরিমাণ 2 জিবি। আপনি অনেক বেশি শারীরিক মেমরির সাথে একটি 64 বিট অপারেটিং সিস্টেমে গিয়ে সীমাটি ভঙ্গ করতে পারেন, তবে এটি করা বা বিকল্পগুলির সন্ধান করা আপনার লক্ষ্যযুক্ত ব্যবহারকারী এবং তাদের বাজেটের উপর খুব বেশি নির্ভর করে। আপনি এটি PAE ব্যবহার করে কিছুটা বাড়িয়ে দিতে পারেন ।

অ্যারের ধরণটি খুব গুরুত্বপূর্ণ, কারণ অনেকগুলি সংকলকগুলিতে ডিফল্ট কাঠামোর প্রান্তিককরণটি 8 বাইট হয়, যা মেমরির ব্যবহারের ক্ষেত্রে যদি কোনও সমস্যা হয় তবে এটি খুব অপ্রয়োজনীয়। যদি আপনি উইন্ডোজকে টার্গেট করতে ভিজ্যুয়াল সি ++ ব্যবহার করেন তবে এটি অতিক্রম করার উপায় হিসাবে # প্রগমা প্যাক নির্দেশিকাটি দেখুন।

আর একটি জিনিস করণীয় যা মেমরি সংকোচনের কৌশলগুলিতে আপনাকে কীভাবে সহায়তা করতে পারে, যেমন স্পয়ার ম্যাট্রিকেস, ফ্লাই সংকোচনে ইত্যাদি ... আবার এটি অত্যন্ত প্রয়োগ নির্ভর করে। আপনি যদি আপনার পোস্টটিতে সম্পাদনা করে থাকেন তবে আপনার অ্যারেগুলিতে কী রয়েছে সে সম্পর্কে আরও কিছু তথ্য দিন, আপনি আরও দরকারী উত্তর পেতে পারেন।

সম্পাদনা করুন: আপনার যথাযথ প্রয়োজনীয়তার উপর কিছুটা বেশি তথ্য দেওয়া হলেও, আপনার স্টোরেজটির প্রয়োজনীয়তা .6..6 গিগাবাইট থেকে 76 76 গিগাবাইটের মধ্যে বিহীন বলে মনে হচ্ছে, যার জন্য সি ++ এ মেমরির অ্যারে হিসাবে সঞ্চয় করার জন্য একটি ব্যয়বহুল bit৪ বিট বাক্সের প্রয়োজন হবে। এটি প্রশ্নটি উত্থাপন করে আপনি কেন মেমরিতে ডেটা সঞ্চয় করতে চান, যেখানে অ্যাক্সেসের গতির জন্য কেউ অনুমান করে এবং এলোমেলো অ্যাক্সেসের অনুমতি দেয়। অ্যারের বাইরে এই ডেটা সংরক্ষণ করার সর্বোত্তম উপায়টি আপনি কীভাবে এটি অ্যাক্সেস করতে চান তার উপর ভিত্তি করে। আপনার যদি অ্যারে সদস্যদের এলোমেলোভাবে অ্যাক্সেস করতে হয় তবে বেশিরভাগ অ্যাপ্লিকেশনগুলির জন্য একই সাথে অ্যাক্সেস করার ঝোঁকযুক্ত ডেটাগুলির ক্লাম্পিংয়ের উপায় রয়েছে। উদাহরণস্বরূপ, বৃহত জিআইএস এবং স্থানিক ডাটাবেসে ডেটা প্রায়শই ভৌগলিক অঞ্চল দ্বারা টাইল হয়ে যায়। সি ++ প্রোগ্রামিংয়ের পদগুলিতে আপনি প্রয়োজন অনুসারে বাহ্যিক স্টোরেজ থেকে আপনার ডেটার অংশ আনতে অ্যারে অপারেটরটিকে ওভাররাইড করতে পারেন।


1
সিস্টেম কল রয়েছে যা প্রোগ্রামের জায়গার বাইরে মেমরির বরাদ্দ দেয়; তবে এটি ওএস নির্ভর এবং বহনযোগ্য নয়। আমরা সেগুলি এম্বেড থাকা সিস্টেমে ব্যবহার করেছি।
থমাস ম্যাথিউস

4

আমি উপরোক্ত সাথে একমত হব, আপনি যদি আপনার অ্যারের সাথে অন্তর্নিবেশ করছেন তবে

 int myArray[SIZE] 

তারপরে SIZE একটি পূর্ণসংখ্যার আকার দ্বারা সীমাবদ্ধ। তবে আপনি সর্বদা মেমোরির একটি অংশকে ম্যালোক করতে পারেন এবং এটিতে একটি পয়েন্টার রাখতে পারেন, যতক্ষণ আপনি চান যতক্ষণ ম্যালোক NULL ফিরিয়ে দেয় না।


আমি নিশ্চিত নই যে এটি ভুল কিনা, বা আমি আপনাকে বা অন্য কিছু ভুল বুঝেছি। উদাহরণস্বরূপ, এটি এমএসভিসি 17 সংকলক দ্বারা প্রতিরোধ করা হয়েছে: int oops[INT_MAX]{0};এটি উত্পন্ন করেC2148 - total size of array must not exceed 0x7fffffff bytes
kayleeFrye_onDeck

১GB জিবি ডিডিআর ৪ এবং 66%ভিএস ২০১7 এর সাহায্যে উইন্ডোজ 10 এ আমার অ্যাপটি ডিবাগ হিসাবে চালু করার আগে বর্তমানে ব্যবহৃত মেমরির সাথে, আমি কতটা ইনট-অ্যারে দিয়ে আরম্ভ করতে পারি তার একটি অনির্ধারিত সীমা আমার আছে 0। কখনও কখনও আমি 7 257k উপাদান দিয়ে এটি করতে পারি, কখনও কখনও আমি স্ট্যাকের ওভারফ্লো পাই। আমি যদি আমার অ্যাপটিতে মূল এবং অ্যারের পাশাপাশি কিছু যোগ করি তবে সেই সংখ্যাটি নিচে নেমে যায় (স্পষ্টতই)। এই সংখ্যাটি নির্ধারণ করার জন্য আমাকে পরীক্ষা-নিরীক্ষা করতে হয়েছিল, তাই শূন্যে আপনার তাত্ত্বিক সীমাটি জেনেও কীভাবে এই মেট্রিকের উপর নির্ভর করা যায় তা আমি দেখতে পাচ্ছি না।
kayleeFrye_onDeck

4

প্রতিক্রিয়াগুলি সংক্ষিপ্ত করতে, সেগুলি প্রসারিত করুন এবং আপনার প্রশ্নের সরাসরি জবাব দিতে:

না, সি ++ অ্যারের মাত্রার জন্য কোনও সীমাবদ্ধতা চাপায় না ।

কিন্তু অ্যারেটি মেমোরিতে কোথাও সংরক্ষণ করতে হয়, তাই কম্পিউটার সিস্টেমের অন্যান্য অংশ দ্বারা আরোপিত মেমরি-সম্পর্কিত সীমা প্রয়োগ হয়। নোট করুন যে এই সীমাগুলি অ্যারের মাত্রা (= উপাদানের সংখ্যা) এর সাথে সরাসরি সম্পর্কিত নয় , বরং এর আকারের সাথে (= মেমোরির পরিমাণ গ্রহণের পরিমাণ)। একটি অ্যারের মাত্রা ( ডি ) এবং ইন-মেমরি আকার ( এস ) এক নয়, কারণ এগুলি একক উপাদান ( ) দ্বারা গৃহীত স্মৃতি দ্বারা সম্পর্কিত : এস = ডি *

এখন নির্ভর করে:

  • অ্যারের উপাদানগুলির ধরণ (উপাদানগুলি ছোট বা বড় হতে পারে)
  • মেমরি সারিবদ্ধকরণ (কর্মক্ষমতা বাড়াতে উপাদানগুলিকে এমন ঠিকানাগুলিতে স্থাপন করা হয় যা কিছু মানের গুণক হয় যা
    উপাদানগুলির মধ্যে 'নষ্ট স্থান' (প্যাডিং) প্রবর্তন করে
  • অবজেক্টের স্ট্যাটিক অংশগুলির আকার (অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিংয়ে একই ধরণের অবজেক্টের স্ট্যাটিক উপাদানগুলি কেবল একবারে সংরক্ষণ করা হয়, যেমন একই ধরণের অবজেক্টের সংখ্যা থেকে পৃথক)

এছাড়াও নোট করুন যে আপনি সাধারণত স্ট্যাকের (অটোমেটিক ভেরিয়েবল হিসাবে int t[N]) অ্যারে ডেটা বরাদ্দ করে ( বা স্বয়ংক্রিয় ভেরিয়েবল হিসাবে ), বা হিপ ( এসটিএল প্রক্রিয়াগুলির সাথে malloc()/ newবা ব্যবহার করে ডায়নামিক বরাদ্দ ) বা প্রক্রিয়া মেমরিটির স্থির অংশে (যেমন হিসাবে) বিভিন্ন মেমরি-সম্পর্কিত সীমাবদ্ধতা পান একটি স্ট্যাটিক ভেরিয়েবল static int t[N]:)। এমনকি যখন গাদাতে বরাদ্দ করা হয় তখনও আপনাকে মেমরির হিপ-বরাদ্দকৃত ব্লকগুলির রেফারেন্সগুলি সঞ্চয় করতে স্ট্যাকের কিছু পরিমাণ মেমরি দরকার (তবে এটি সাধারণত তুচ্ছ নয়)। প্রকারের

আকারের size_tকোনও প্রকারের প্রভাব নেই (আমি ধরে নিই যে প্রোগ্রামার size_tইনডেক্সিংয়ের জন্য টাইপ ব্যবহার করে, যেমন এটি এর জন্য ডিজাইন করা হয়েছে), কারণ সংকলক সরবরাহকারীর typedefপ্রদত্ত প্ল্যাটফর্মের জন্য সর্বাধিক পরিমাণের মেমরির সম্বোধন করতে যথেষ্ট পরিমাণে একটি পূর্ণসংখ্যার সংযুক্তি রয়েছে স্থাপত্য।

মেমরি-আকারের সীমাবদ্ধতার উত্সগুলি থেকে এসেছে

  • প্রক্রিয়াটিতে উপলব্ধ মেমরির পরিমাণ (যা 32-বিট অ্যাপ্লিকেশনগুলির জন্য 2 ^ 32 বাইটের মধ্যে সীমাবদ্ধ, এমনকি 64৪-বিট ওএস কার্নেলগুলিতেও),
  • প্রক্রিয়া মেমরির বিভাগ (উদাহরণস্বরূপ স্ট্যাক বা গাদা জন্য ডিজাইন করা প্রক্রিয়া মেমরির পরিমাণ),
  • শারীরিক মেমরির বিভাজন (অনেকগুলি ছড়িয়ে ছিটিয়ে থাকা ছোট ছোট ফ্রি মেমরির টুকরোগুলি একটি একক কাঠামো সংরক্ষণের জন্য প্রযোজ্য নয়),
  • শারীরিক স্মৃতি পরিমাণ
  • এবং ভার্চুয়াল মেমরি পরিমাণ।

অ্যাপ্লিকেশন পর্যায়ে এগুলি 'টুইট করা' যাবে না, তবে আপনি আলাদা সংকলক (স্ট্যাকের আকার সীমা পরিবর্তন করতে), বা আপনার অ্যাপ্লিকেশনটিকে 64৪-বিটগুলিতে পোর্ট করতে, বা অন্য ওএসে পোর্ট করতে বা শারীরিক / (ভার্চুয়াল? শারীরিক?) মেশিনের ভার্চুয়াল মেমরি কনফিগারেশন।

উপরের সমস্ত বিষয়গুলি বাহ্যিক অশান্তি হিসাবে বিবেচনা করা এবং এভাবে রানটাইম ত্রুটির সম্ভাব্য উত্স হিসাবে বিবেচনা করা এবং আপনার প্রোগ্রামের কোডে মেমরি-বরাদ্দ সম্পর্কিত ত্রুটিগুলি সাবধানতার সাথে পরীক্ষা করা এবং প্রতিক্রিয়া জানানো অস্বাভাবিক নয় (এবং এমনকি পরামর্শযুক্ত )ও নয়।

সুতরাং শেষ অবধি: সি ++ কোনও সীমাবদ্ধতা চাপিয়ে দিচ্ছে না, আপনার কোডটি চালানোর সময় আপনাকে এখনও প্রতিকূল মেমরি-সম্পর্কিত অবস্থার জন্য পরীক্ষা করতে হবে ... :-)


3

অনেকগুলি উত্তরের হিসাবে উল্লেখ করা হয়েছে, অনেকগুলি সীমাবদ্ধতা রয়েছে যা আপনার সি ++ সংকলক, অপারেটিং সিস্টেম এবং কম্পিউটারের বৈশিষ্ট্যগুলির সংস্করণে নির্ভর করে। যাইহোক, আমি পাইথনে নিম্নলিখিত স্ক্রিপ্টটি পরামর্শ দিচ্ছি যা আপনার মেশিনের সীমা পরীক্ষা করে।

এটি বাইনারি অনুসন্ধান ব্যবহার করে এবং প্রতিটি পুনরাবৃত্তির পরীক্ষা করে যদি মাঝারি আকারটি এমন একটি কোড তৈরি করে সম্ভব হয় যা আকারের একটি অ্যারে তৈরি করার চেষ্টা করে। স্ক্রিপ্ট এটি সংকলন করার চেষ্টা করে (দুঃখিত, এই অংশটি কেবল লিনাক্সে কাজ করে) এবং সাফল্যের উপর নির্ভর করে বাইনারি অনুসন্ধান সামঞ্জস্য করে। এটা দেখ:

import os

cpp_source = 'int a[{}]; int main() {{ return 0; }}'

def check_if_array_size_compiles(size):
        #  Write to file 1.cpp
        f = open(name='1.cpp', mode='w')
        f.write(cpp_source.format(m))
        f.close()
        #  Attempt to compile
        os.system('g++ 1.cpp 2> errors')
        #  Read the errors files
        errors = open('errors', 'r').read()
        #  Return if there is no errors
        return len(errors) == 0

#  Make a binary search. Try to create array with size m and
#  adjust the r and l border depending on wheather we succeeded
#  or not
l = 0
r = 10 ** 50
while r - l > 1:
        m = (r + l) // 2
        if check_if_array_size_compiles(m):
                l = m
        else:
                r = m

answer = l + check_if_array_size_compiles(r)
print '{} is the maximum avaliable length'.format(answer)

আপনি এটি আপনার মেশিনে সংরক্ষণ করতে এবং এটি চালু করতে পারেন এবং এটি আপনার তৈরি করা সর্বোচ্চ আকার মুদ্রণ করবে। আমার মেশিনের জন্য এটি 2305843009213693951।


2

আমার মনে হয় না এমন একটি জিনিস যা পূর্ববর্তী উত্তরে উল্লেখ করা হয়েছিল।

লোকেরা যখন তাদের নকশায় এ জাতীয় জিনিস ব্যবহার করে তখন আমি রিফেকচারিং অর্থে সর্বদা একটি "দুর্গন্ধ" সংবেদন করি।

এটি একটি বিশাল অ্যারে এবং সম্ভবত দক্ষতার দিক থেকে এবং পারফরম্যান্সের দিক থেকে আপনার ডেটা উপস্থাপনের সর্বোত্তম উপায় নয়।

চিয়ার্স,

হরণ করা


আমার কী ব্যবহার করা উচিত সে সম্পর্কে আপনার কোনও পরামর্শ আছে?
লুইস

আপনি যদি আমাদের কীভাবে ডেটা সংরক্ষণ করছেন তা যদি আমাদের বলতে পারেন তবে আমরা পারি। (-:
রব ওয়েলস

দুঃখিত লুইস আমার প্রথম প্রতিক্রিয়া খুব ফ্লিপ্যান্ট ছিল। এটি আপনার ডেটার প্রকৃতি দ্বারা চালিত হবে। আপনার ডেটার রিলেশনশিপগুলি ডেটা উপস্থাপনের জন্য আপনি যে মডেলটি ব্যবহার করবেন তা চালিত করবে। তারপরে সংগ্রহটি এ থেকে স্পষ্ট হওয়া উচিত । যদি তা না হয় তবে আমি ডেটা মডেলটি নিয়ে চিন্তা করব।
রব ওয়েলস

আমার কাছে এতটা উল্টাপাল্টা নয়: এই জাতীয় খেলনাযুক্ত ক্যাশেড ডাটাবেস সম্পর্কে কীভাবে? টুইটটাউন

2

আপনার যদি এত বড় ডেটার সাথে ডিল করতে হয় তবে আপনাকে এটিকে ম্যানেজযোগ্য খণ্ডে বিভক্ত করতে হবে। এটি সমস্ত কোনও ছোট কম্পিউটারের মেমরির সাথে খাপ খায় না। আপনি সম্ভবত ডিস্ক থেকে ডেটার একটি অংশ লোড করতে পারেন (যাই হোক না কেন যুক্তিসঙ্গতভাবে মাপসই হয়), আপনার গণনা সম্পাদন করুন এবং এতে পরিবর্তন করুন, এটি ডিস্কে সঞ্চয় করুন, এবং সম্পূর্ণ না হওয়া পর্যন্ত পুনরাবৃত্তি করুন।


মেমরিতে ফিট করার জন্য খুব বড় ডেটা হ্যান্ডেল করতে একটি উদাহরণ অ্যালগরিদমকে মার্জ করুন এর জন্যও দেখুন।
থমাস ম্যাথিউস

2

সমস্ত বর্তমান উত্তর হিসাবে বিরক্তিকরভাবে অ-নির্দিষ্ট হিসাবে, সেগুলি বেশিরভাগ ক্ষেত্রে সঠিক তবে অনেকগুলি সতর্কতার সাথে, সর্বদা উল্লেখ করা হয় না। বাক্যটি হ'ল, আপনার দুটি উচ্চ-সীমা রয়েছে এবং এর মধ্যে কেবল একটিরই আসলে সংজ্ঞায়িত কিছু, তাই ওয়াইএমএমভি :

1. সংকলন-সময় সীমা

মূলত, আপনার সংকলকটি কী অনুমতি দেবে। এক্স x64 উইন্ডোজ 10 বাক্সে ভিজ্যুয়াল সি ++ 2017 এর জন্য 2 জিবি সীমাবদ্ধতার আগে কমপাইল সময়ে এটি আমার সর্বাধিক সীমা,

unsigned __int64 max_ints[255999996]{0};

আমি যদি এর পরিবর্তে এটি করি,

unsigned __int64 max_ints[255999997]{0};

আমি পেয়েছি:

Error C1126 automatic allocation exceeds 2G

আমি নিশ্চিত কিভাবে 2G থেকে correllates নই 255999996/ 7। আমি উভয় সংখ্যা গুগল করেছিলাম এবং কেবলমাত্র আমি খুঁজে পেতাম যে সম্ভবত এটি সম্পর্কিত ছিল এটি ছিল * নিক্স প্রশ্নোত্তর সাথে একটি নির্ভুলতার সমস্যা সম্পর্কেdc । যে কোনও উপায়ে, আপনি কোন ধরণের ইন্টি অ্যারে পূরণ করার চেষ্টা করছেন তা ঠিক মনে হচ্ছে না, ঠিক কতগুলি উপাদান বরাদ্দ করা যেতে পারে।

2. রান-সময় সীমা

আপনার স্ট্যাক এবং গাদা তাদের নিজস্ব সীমাবদ্ধতা আছে। এই সীমাগুলি উভয় মান যা উপলব্ধ সিস্টেম সংস্থার উপর ভিত্তি করে পরিবর্তিত হয়, পাশাপাশি আপনার অ্যাপ্লিকেশনটি কতটা "ভারী"। উদাহরণস্বরূপ, আমার বর্তমান সিস্টেম সংস্থান দিয়ে, আমি এটি চালাতে পারি:

int main()
{
    int max_ints[257400]{ 0 };
    return 0;
}

তবে আমি যদি কিছুটা টুইট করি তবে ...

int main()
{
    int max_ints[257500]{ 0 };
    return 0;
}

বাম! ওভারফ্লো স্ট্যাক!

Exception thrown at 0x00007FF7DC6B1B38 in memchk.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000AA8DE03000). Unhandled exception at 0x00007FF7DC6B1B38 in memchk.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000AA8DE03000).

এবং কেবলমাত্র আপনার অ্যাপের পয়েন্টের সম্পূর্ণ ভারাক্রান্তি বিশদটি বিশদে, এটি যেতে ভাল হয়েছিল:

int main()
{
    int maxish_ints[257000]{ 0 };
    int more_ints[400]{ 0 };
    return 0;
}  

তবে এটি স্ট্যাকের উপচে পড়েছে:

int main()
{
    int maxish_ints[257000]{ 0 };
    int more_ints[500]{ 0 };
    return 0;
}  

1

আমি অবাক হই যে স্টাড :: ভেক্টরের ম্যাক্স_সাইজ () সদস্য ফাংশনটি এখানে উল্লেখ করা হয়নি।

"সিস্টেম বা গ্রন্থাগার বাস্তবায়নের সীমাবদ্ধতার কারণে ধারকটি ধারণ করতে সক্ষম সংখ্যক সর্বাধিক সংখ্যক উপাদানকে ফেরত দেয়, যেমন বৃহত্তর ধারকটির জন্য স্ট্যান্ড :: দূরত্ব (শুরু (), শেষ ())" "

আমরা জানি যে std::vectorহুডের নীচে একটি গতিশীল অ্যারে হিসাবে প্রয়োগ করা হয়েছে, সুতরাং আপনার মেশিনে গতিশীল অ্যারের max_size()সর্বাধিক দৈর্ঘ্যের খুব কাছাকাছি অনুমান করা উচিত ।

নিম্নলিখিত প্রোগ্রামটি বিভিন্ন ডেটা ধরণের জন্য আনুমানিক সর্বাধিক অ্যারে দৈর্ঘ্যের একটি সারণী তৈরি করে।

#include <iostream>
#include <vector>
#include <string>
#include <limits>

template <typename T>
std::string mx(T e) {
    std::vector<T> v;
    return std::to_string(v.max_size());
}

std::size_t maxColWidth(std::vector<std::string> v) {
    std::size_t maxWidth = 0;

    for (const auto &s: v)
        if (s.length() > maxWidth)
            maxWidth = s.length();

    // Add 2 for space on each side
    return maxWidth + 2;
}

constexpr long double maxStdSize_t = std::numeric_limits<std::size_t>::max();

// cs stands for compared to std::size_t
template <typename T>
std::string cs(T e) {
    std::vector<T> v;
    long double maxSize = v.max_size();
    long double quotient = maxStdSize_t / maxSize;
    return std::to_string(quotient);
}

int main() {
    bool v0 = 0;
    char v1 = 0;

    int8_t v2 = 0;
    int16_t v3 = 0;
    int32_t v4 = 0;
    int64_t v5 = 0;

    uint8_t v6 = 0;
    uint16_t v7 = 0;
    uint32_t v8 = 0;
    uint64_t v9 = 0;

    std::size_t v10 = 0;
    double v11 = 0;
    long double v12 = 0;

    std::vector<std::string> types = {"data types", "bool", "char", "int8_t", "int16_t",
                                      "int32_t", "int64_t", "uint8_t", "uint16_t",
                                      "uint32_t", "uint64_t", "size_t", "double",
                                      "long double"};

    std::vector<std::string> sizes = {"approx max array length", mx(v0), mx(v1), mx(v2),
                                      mx(v3), mx(v4), mx(v5), mx(v6), mx(v7), mx(v8),
                                      mx(v9), mx(v10), mx(v11), mx(v12)};

    std::vector<std::string> quotients = {"max std::size_t / max array size", cs(v0),
                                          cs(v1), cs(v2), cs(v3), cs(v4), cs(v5), cs(v6),
                                          cs(v7), cs(v8), cs(v9), cs(v10), cs(v11), cs(v12)};

    std::size_t max1 = maxColWidth(types);
    std::size_t max2 = maxColWidth(sizes);
    std::size_t max3 = maxColWidth(quotients);

    for (std::size_t i = 0; i < types.size(); ++i) {
        while (types[i].length() < (max1 - 1)) {
            types[i] = " " + types[i];
        }

        types[i] += " ";

        for  (int j = 0; sizes[i].length() < max2; ++j)
            sizes[i] = (j % 2 == 0) ? " " + sizes[i] : sizes[i] + " ";

        for  (int j = 0; quotients[i].length() < max3; ++j)
            quotients[i] = (j % 2 == 0) ? " " + quotients[i] : quotients[i] + " ";

        std::cout << "|" << types[i] << "|" << sizes[i] << "|" << quotients[i] << "|\n";
    }

    std::cout << std::endl;

    std::cout << "N.B. max std::size_t is: " <<
        std::numeric_limits<std::size_t>::max() << std::endl;

    return 0;
}

আমার ম্যাকোজে (ঝাঁকুনা সংস্করণ 5.0.1), আমি নিম্নলিখিতগুলি পেয়েছি:

|  data types | approx max array length | max std::size_t / max array size |
|        bool |   9223372036854775807   |             2.000000             |
|        char |   9223372036854775807   |             2.000000             |
|      int8_t |   9223372036854775807   |             2.000000             |
|     int16_t |   9223372036854775807   |             2.000000             |
|     int32_t |   4611686018427387903   |             4.000000             |
|     int64_t |   2305843009213693951   |             8.000000             |
|     uint8_t |   9223372036854775807   |             2.000000             |
|    uint16_t |   9223372036854775807   |             2.000000             |
|    uint32_t |   4611686018427387903   |             4.000000             |
|    uint64_t |   2305843009213693951   |             8.000000             |
|      size_t |   2305843009213693951   |             8.000000             |
|      double |   2305843009213693951   |             8.000000             |
| long double |   1152921504606846975   |             16.000000            |

N.B. max std::size_t is: 18446744073709551615

উপর ideone জিসিসি 8.3 আমি পাবেন:

|  data types | approx max array length | max std::size_t / max array size |
|        bool |   9223372036854775744   |             2.000000             |
|        char |   18446744073709551615  |             1.000000             |
|      int8_t |   18446744073709551615  |             1.000000             |
|     int16_t |   9223372036854775807   |             2.000000             |
|     int32_t |   4611686018427387903   |             4.000000             |
|     int64_t |   2305843009213693951   |             8.000000             |
|     uint8_t |   18446744073709551615  |             1.000000             |
|    uint16_t |   9223372036854775807   |             2.000000             |
|    uint32_t |   4611686018427387903   |             4.000000             |
|    uint64_t |   2305843009213693951   |             8.000000             |
|      size_t |   2305843009213693951   |             8.000000             |
|      double |   2305843009213693951   |             8.000000             |
| long double |   1152921504606846975   |             16.000000            |

N.B. max std::size_t is: 18446744073709551615

এটি লক্ষ করা উচিত যে এটি একটি তাত্ত্বিক সীমা এবং বেশিরভাগ কম্পিউটারে আপনি এই সীমাটি পৌঁছানোর অনেক আগেই মেমরির বাইরে চলে যাবেন। উদাহরণস্বরূপ, আমরা দেখতে পাই যে টাইপের charজন্য gcc, উপাদানগুলির সর্বাধিক সংখ্যা সর্বাধিকের সমান std::size_t। চেষ্টা এই , আমরা ভুল পান:

prog.cpp: In function int main()’:
prog.cpp:5:61: error: size of array is too large
  char* a1 = new char[std::numeric_limits<std::size_t>::max()];

অবশেষে, @ মার্টিনইয়র্কটি দেখায় যে, স্ট্যাটিক অ্যারেগুলির জন্য আপনার স্ট্যাকের আকার দ্বারা সর্বাধিক আকার সীমাবদ্ধ।


0

যেমন ইতিমধ্যে চিহ্নিত করা হয়েছে, অ্যারে আকারটি আপনার হার্ডওয়্যার এবং আপনার ওএস (ম্যান উলিমিট) দ্বারা সীমাবদ্ধ। আপনার সফ্টওয়্যার যদিও, কেবল আপনার সৃজনশীলতার দ্বারা সীমাবদ্ধ হতে পারে। উদাহরণস্বরূপ, আপনি কি ডিস্কে আপনার "অ্যারে" সঞ্চয় করতে পারেন? আপনার কি সত্যিই দীর্ঘ দীর্ঘ ইনটগুলি দরকার? আপনার কি সত্যিই ঘন অ্যারে দরকার? এমনকি আপনার কি আদৌ দরকার হয়?

একটি সহজ সমাধান হ'ল .৪ বিট লিনাক্স ব্যবহার করা। এমনকি যদি আপনার অ্যারের জন্য শারীরিকভাবে পর্যাপ্ত পরিমাণে র্যাম না থাকে তবে ওএস আপনাকে মেমরির বরাদ্দ করতে দেয় যেমন আপনার প্রক্রিয়ায় উপলব্ধ ভার্চুয়াল মেমরিটি সম্ভবত শারীরিক মেমরির চেয়ে অনেক বড়। আপনার যদি অ্যারেতে সত্যিই অ্যাক্সেসের প্রয়োজন হয় তবে এটি ডিস্কে এটি সঞ্চয় করার সমান। আপনার অ্যাক্সেসের ধরণগুলির উপর নির্ভর করে এটি করার আরও কার্যকর উপায় থাকতে পারে (যেমন: এমএমএপি () ব্যবহার করা, বা কেবল কোনও ফাইলের মধ্যে ধারাবাহিকভাবে ডেটা সংরক্ষণ করা (যার ক্ষেত্রে 32 বিট লিনাক্স যথেষ্ট হবে)।


2
হুম, ডিস্ক, অ্যারে, ... ভার্চুয়াল মেমরির যে কেউ শুনবে । ভার্চুয়াল মেমোরি সমর্থন করে এমন ওএসগুলি মেমরির জন্য একটি বাহ্যিক ডিভাইস যেমন একটি হার্ড ডিস্ক ব্যবহার করা শুরু করবে এবং অভ্যন্তরীণ মেমরির অংশগুলি অদলবদল করবে।
থমাস ম্যাথিউ

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.