Malloc () এবং বিনামূল্যে () কীভাবে কাজ করে?


276

আমি কিভাবে mallocএবং freeকাজ জানতে চাই ।

int main() {
    unsigned char *p = (unsigned char*)malloc(4*sizeof(unsigned char));
    memset(p,0,4);
    strcpy((char*)p,"abcdabcd"); // **deliberately storing 8bytes**
    cout << p;
    free(p); // Obvious Crash, but I need how it works and why crash.
    cout << p;
    return 0;
}

উত্তরটি যদি মেমরি স্তরের গভীরতায় হয়, তবে এটি সম্ভব হলে আমি সত্যিই কৃতজ্ঞ হব।


5
এটি কি সংকলক এবং ব্যবহৃত রানটাইম লাইব্রেরির উপর নির্ভর করে না?
ভিলক্স-

9
যা সিআরটি বাস্তবায়নের উপর নির্ভর করবে। সুতরাং আপনি এটি সাধারণ করতে পারবেন না।
নবীন

58
এই স্ট্রিপিপি 9 টি বাইট লিখেছেন, 8 নয় not নুল টার্মিনেটরটি ভুলে যাবেন না ;-)।
ইভান তেরান


2
@ LưuVĩnhPhúc এটি সি ++। নোট করুনcout <<
ব্র্যাডেন সেরা

উত্তর:


385

ঠিক আছে malloc সম্পর্কে কিছু উত্তর ইতিমধ্যে পোস্ট করা হয়েছে।

আরও আকর্ষণীয় অংশটি হ'ল কীভাবে নিখরচায় কাজ করে (এবং এই দিকে, ম্যালোককে আরও ভাল বোঝা যায়)।

অনেক ম্যালোক / ফ্রি বাস্তবায়নে, ফ্রি সাধারণত অপারেটিং সিস্টেমে মেমরি ফিরিয়ে দেয় না (বা কমপক্ষে কেবল বিরল ক্ষেত্রে)। কারণটি হ'ল আপনি আপনার গাদা ফাঁক পেয়ে যাবেন এবং এটি ঘটতে পারে, আপনি কেবল আপনার 2 বা 4 জিবি ভার্চুয়াল মেমরি ফাঁক দিয়ে শেষ করে ফেলবেন। এটি এড়ানো উচিত, যেহেতু ভার্চুয়াল মেমরিটি শেষ হওয়ার সাথে সাথে আপনি সত্যিই বড় সমস্যায় পড়বেন। অন্য কারণটি হ'ল, ওএস কেবলমাত্র একটি নির্দিষ্ট আকার এবং প্রান্তিককরণের মেমরি খণ্ডগুলি পরিচালনা করতে পারে। সুনির্দিষ্ট হতে হবে: সাধারণত ওএস ভার্চুয়াল মেমরি পরিচালক যে ব্লকগুলি পরিচালনা করতে পারে কেবল তা পরিচালনা করতে পারে (প্রায়শই 512 বাইট যেমন 4KB এর গুণক)।

সুতরাং ওএস এ 40 বাইট ফিরিয়ে দেওয়া ঠিক কাজ করবে না। তাহলে ফ্রি কী করে?

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

ফ্রি-লিস্টটিও প্রথম স্থান যেখানে ম্যালোক দেখায় যখন একটি নতুন অংশের মেমরি প্রয়োজন হয়। এটি ওএস থেকে নতুন মেমরির কল করার আগে এটি স্ক্যান করা হয়। যখন কোনও অংশ খুঁজে পাওয়া যায় যা প্রয়োজনীয় মেমরির চেয়ে বড়, এটি দুটি ভাগে বিভক্ত হয়। একজনকে কলারে ফিরিয়ে দেওয়া হয়, অন্যটিকে ফ্রি তালিকায় ফেলা হয়।

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

কেন আপনার কোড ক্রাশ করে:

কারণটি হ'ল 4 টি অক্ষরের জন্য 9 টি অক্ষর (পিছনের নাল বাইটটি ভুলে যাবেন না) লিখে আপনি সম্ভবত মেমরির অন্য অংশের জন্য সঞ্চিত প্রশাসনিক-তথ্যটি ওভাররাইট করে ফেলতে পারবেন যা আপনার "ডেটা" অংশের পিছনে থাকে ( যেহেতু এই ডেটাটি প্রায়শই মেমরি খণ্ডগুলির "সামনে" সঞ্চিত থাকে)। যখন ফ্রি থাকে তখন আপনার খণ্ডটিকে ফ্রি তালিকায় রাখার চেষ্টা করে, এটি প্রশাসনিক-ডেটাটিকে স্পর্শ করতে পারে এবং তাই একটি ওভাররাইট পয়েন্টারটিতে হোঁচট খেতে পারে। এটি সিস্টেমটি ক্রাশ করবে।

এটি বরং কৌতূহলপূর্ণ আচরণ। আমি এমন পরিস্থিতিও দেখেছি যেখানে কোনও পলাতক পয়েন্টারটি কোথাও মেমরি-মুক্ত-তালিকায় ডেটা ওভাররাইট করে এবং সিস্টেমটি তত্ক্ষণাত ক্রাশ হয় নি তবে কিছু সাব্রোটাইন পরে রয়েছে। এমনকি মাঝারি জটিলতার ব্যবস্থায় এ জাতীয় সমস্যাগুলি সত্যই, ডিবাগ করা সত্যিই কঠিন হতে পারে! আমি যে মামলায় জড়িত ছিলাম তাতে ক্র্যাশটির কারণ খুঁজে পেতে আমাদের (বিকাশকারীদের একটি বৃহত্তর দল) বেশ কয়েক দিন সময় লেগেছিল - যেহেতু এটি মেমরি ডাম্প দ্বারা নির্দেশিত চেয়ে সম্পূর্ণ ভিন্ন অবস্থানে ছিল। এটি একটি টাইম বোমার মতো। আপনি জানেন, আপনার পরবর্তী "ফ্রি" বা "ম্যালোক" ক্র্যাশ হবে, তবে আপনি জানেন না কেন!

সেগুলি হ'ল সবচেয়ে খারাপ সি / সি ++ সমস্যা এবং পয়েন্টারগুলি কেন এতটা সমস্যাযুক্ত হতে পারে তার একটি কারণ।


62
খুব বেশি লোক বুঝতে পারে না যে ফ্রি () ওএস-এ মেমরি ফিরিয়ে দিতে পারে না, এটি বিরক্তিকর। তাদের আলোকিত করতে সাহায্য করার জন্য ধন্যবাদ।
আর্টিলিয়াস

আর্টিলিয়াস: বিপরীতে, নতুন কি সবসময়ই ঘটে?
গিলোয়াম07

3
@ গুইলাউম07 আমি ধরে নিয়েছি আপনি মুছে ফেলার অর্থ নতুন নয়। না, এটি (প্রয়োজনীয়ভাবে) হয় না। মুছুন এবং বিনামূল্যে (প্রায়) একই জিনিস। এমএসভিসি ২০১৩ এ প্রত্যেকে যে কোডগুলি কল করেছে তা এখানে: goo.gl/3O2Kyu
Yay295

1
মুছুন সর্বদা ধ্বংসকারীকে কল করবে, তবে স্মৃতি নিজেই পরে বরাদ্দের জন্য একটি ফ্রি-তালিকায় যেতে পারে। প্রয়োগের উপর নির্ভর করে, এটি এমনকি একই ফ্রি-তালিকা হতে পারে যা ম্যালোক ব্যবহার করে।
ডেভিড সি

1
@ জুগারজেন কিন্তু ফ্রি () অতিরিক্ত বাইট পড়ুন যেখানে ম্যালোক থেকে কত পরিমাণ মেমরি বরাদ্দ করা হয়েছে তা তথ্য রয়েছে, এটি ৪ পেয়ে যায় Then তারপরে ক্র্যাশ কীভাবে ঘটল বা কতটা মুক্ত () প্রশাসনিক ডেটা স্পর্শ করবেন?
আচরণ

56

যেমন Aluser এই ফোরামে থ্রেডে বলেছেন :

আপনার প্রক্রিয়াটির ঠিকানা x থেকে ঠিকানা y পর্যন্ত মেমরির একটি অঞ্চল রয়েছে, তাকে হিপ বলা হয়। আপনার সমস্ত malloc'd ডেটা এই অঞ্চলে বাস করে। malloc () কিছু তথ্য কাঠামো রাখে, আসুন একটি তালিকা বলি, গাদা সমস্ত ফাঁকা স্থানের তালিকা। আপনি যখন ম্যালোককে কল করেন তখন তালিকার মধ্যে এটি দেখতে পাওয়া যায় যা আপনার পক্ষে যথেষ্ট বড়, এটিতে একটি পয়েন্টার ফিরিয়ে দেয় এবং সত্য যে এটি আর মুক্ত নয় তেমনি এটি কত বড়। আপনি যখন একই পয়েন্টার দিয়ে ফ্রি () কল করেন তখন ফ্রি () সেই খণ্ডটি কত বড় তা দেখায় এবং এটিকে ফ্রি অংশগুলির তালিকায় আবার যুক্ত করে ()। যদি আপনি মলোককে () কল করেন এবং এটি স্তূপে কোনও বৃহত পরিমাণ খুঁজে না পেয়ে থাকে তবে এটি স্তূপ বাড়ানোর জন্য ব্র্যাক () সিস্কল ব্যবহার করে, যেমন ঠিকানা y বৃদ্ধি করে এবং পুরাতন y এবং নতুন y এর মধ্যে সমস্ত ঠিকানা তৈরি করে বৈধ মেমরি হতে। brk () অবশ্যই একটি সিস্টাল হতে হবে;

malloc () হ'ল সিস্টেম / সংকলক নির্ভর তাই নির্দিষ্ট উত্তর দেওয়া শক্ত। মূলত তবে এটি কী মেমোরি বরাদ্দ করেছে এবং কীভাবে এটি করা হয় তার উপর নির্ভর করে আপনার কলগুলি ফ্রি করতে বা সফল হতে পারে তার উপর নির্ভর করে।

malloc() and free() don't work the same way on every O/S.


1
এ কারণেই এটিকে অপরিজ্ঞাত আচরণ বলে। আপনি যখন কোনও অবৈধ লেখার পরে ফ্রি কল করেন তখন একটি বাস্তবায়ন রাক্ষসদের আপনার নাক থেকে উড়ে যেতে পারে। আপনি কখনো জানেন না.
ব্র্যাডেন সেরা

35

ম্যালোক / ফ্রি এর একটি বাস্তবায়ন নিম্নলিখিতগুলি করে:

  1. Sbrk () (ইউনিক্স কল) এর মাধ্যমে ওএস থেকে মেমরির একটি ব্লক পান।
  2. আকার, অনুমতি এবং যেখানে পরবর্তী এবং পূর্ববর্তী ব্লকটি রয়েছে তার কিছু তথ্য সহ মেমরির সেই ব্লকের চারপাশে একটি শিরোনাম এবং একটি পাদচরণ তৈরি করুন।
  3. যখন ম্যালোক-এ কল আসে, একটি তালিকা উল্লেখ করা হয় যা উপযুক্ত আকারের ব্লকগুলিকে নির্দেশ করে।
  4. এরপরে এই ব্লকটি ফেরত দেওয়া হয় এবং শিরোনাম এবং পাদচরণ অনুসারে আপডেট করা হয়।

25

মেমরির সুরক্ষায় পৃষ্ঠা-গ্রানুলারিটি থাকে এবং এতে কার্নেল ইন্টারঅ্যাকশন প্রয়োজন

আপনার উদাহরণ কোডটি মূলত উদাহরণস্বরূপ প্রোগ্রামটি কেন ফাঁসবে না, এবং এর উত্তরটি হ'ল মেমরি সুরক্ষা একটি কার্নেল বৈশিষ্ট্য এবং কেবলমাত্র পুরো পৃষ্ঠাগুলিতে প্রযোজ্য, যেখানে মেমরির বরাদ্দকারী একটি লাইব্রেরি বৈশিষ্ট্য এবং এটি পরিচালনা করে .. বাস্তবায়ন ছাড়াই .. নির্বিচারে মাপের ব্লকগুলি যা পৃষ্ঠাগুলির চেয়ে প্রায়শই ছোট।

পৃষ্ঠাগুলির ইউনিটগুলিতে মেমরি কেবল আপনার প্রোগ্রাম থেকে সরানো যেতে পারে এবং এটি পর্যবেক্ষণের সম্ভাবনাও কম।

কলোক (3) এবং ম্যালোক (3) প্রয়োজনবোধে মেমরি পাওয়ার জন্য কার্নেলের সাথে যোগাযোগ করে। কিন্তু ফ্রি (3) এর বেশিরভাগ বাস্তবায়ন কার্নেল 1 এ মেমরি ফিরিয়ে দেয় না , তারা কেবল এটি একটি ফ্রি তালিকায় যুক্ত করে যা কলোক () এবং ম্যালোক () পরে প্রকাশিত ব্লকগুলি পুনরায় ব্যবহার করার জন্য পরামর্শ করবে।

এমনকি যদি কোনও ফ্রি () সিস্টেমে মেমরি ফিরিয়ে নিতে চায়, তবে অঞ্চলটিকে সুরক্ষিত করার জন্য কার্নেলটি পেতে কমপক্ষে একটি স্বতন্ত্র মেমরি পৃষ্ঠার প্রয়োজন হবে, সুতরাং একটি ছোট ব্লক প্রকাশ করলে কেবল সুরক্ষা পরিবর্তন ঘটতে পারে গত একটি পৃষ্ঠায় ছোট ব্লক।

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

  • কখনও কখনও বরাদ্দকারীরা মেমরির পৃথক ব্লকগুলি বজায় রাখে, কখনও কখনও তারা আপনার ব্লকের ঠিক আগে বা পরে বরাদ্দকৃত একটি শিরোলেখ ব্যবহার করে (একটি "পাদলেখ", আমার ধারণা) কেবলমাত্র নিখরচায় তালিকার জন্য তারা ব্লকের মধ্যে মেমরি ব্যবহার করতে চায় একত্রে সম্পর্কিত. যদি তা হয় তবে আপনার ব্লকটি পড়া ঠিক আছে তবে এর সামগ্রীগুলি পরিবর্তন হতে পারে এবং ব্লকে লেখার কারণে বরাদ্দকারীকে খারাপ আচরণ বা ক্রাশ হতে পারে to
  • স্বাভাবিকভাবেই, আপনার ব্লকটি ভবিষ্যতে বরাদ্দ হতে পারে এবং তারপরে এটি আপনার কোড বা একটি লাইব্রেরি রুটিন দ্বারা বা কলোক () দ্বারা জিরো দিয়ে মুছে ফেলা হতে পারে।
  • যদি ব্লকটি পুনরায় স্থানান্তরিত হয়, তবে এটির আকারও পরিবর্তিত হতে পারে, সেক্ষেত্রে আরও অনেক লিঙ্ক বা প্রারম্ভিককরণ বিভিন্ন স্থানে লেখা হবে।
  • স্পষ্টতই আপনি এতদূর সীমার বাইরে রেফারেন্স দিতে পারেন যে আপনি আপনার প্রোগ্রামের কার্নেল-পরিচিত অংশগুলির একটি সীমানা অতিক্রম করেছেন এবং এই এক ক্ষেত্রে আপনি ফাঁদে যাবেন।

কার্যপ্রণালীর তত্ত্ব

সুতরাং, আপনার উদাহরণ থেকে সামগ্রিক তত্ত্বের দিকে পিছনে কাজ করা, ম্যালোক (3) কার্নেলের প্রয়োজন হলে এবং সাধারণত পৃষ্ঠাগুলির ইউনিটে মেমরি পায় gets প্রোগ্রামটি যেমন প্রয়োজন তেমন এই পৃষ্ঠাগুলি বিভক্ত বা একীভূত হয়। মেলোক এবং নিখরচায় একটি ডিরেক্টরি বজায় রাখতে সহযোগিতা করুন। বৃহত ব্লক সরবরাহ করতে সক্ষম হওয়ার জন্য তারা যখন সম্ভব সংলগ্ন ফ্রি ব্লকগুলি একত্রিত করে। ডিরেক্টরিটি লিঙ্কযুক্ত তালিকা গঠনের জন্য ফ্রি ব্লকগুলিতে মেমরিটি ব্যবহার করে বা না জড়িত। (বিকল্পটি আরও কিছু অংশীদারি-মেমরি এবং পেজিং-বান্ধব এবং এতে বিশেষত ডিরেক্টরিতে মেমরি বরাদ্দ করা জড়িত)) বিশেষ এবং andচ্ছিক ডিবাগিং কোডটি সংকলিত হলেও পৃথক ব্লকগুলিতে অ্যাক্সেস প্রয়োগের কোনও ক্ষমতা থাকলে ম্যালোক এবং ফ্রি খুব কমই থাকে have কার্যক্রম.


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


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

23

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

আপনি যখন 4 বাইট বরাদ্দ করেন, উদাহরণস্বরূপ, malloc আপনাকে 4 বাইটে পয়েন্টার দেয়। আপনি যা বুঝতে পারবেন না তা হ'ল স্মৃতিটি 8-12 বাইট আগে আপনার 4 বাইট malloc দ্বারা ব্যবহৃত হচ্ছে সব স্মৃতি আপনি বরাদ্দ আছে একটা চেন না। আপনি যখন ফ্রি কল করেন তখন এটি আপনার পয়েন্টারটি নেবে, যেখানে এটির ডেটা রয়েছে সেখানে ব্যাক আপ করে এবং তার উপর পরিচালিত হয়।

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

অস্বীকৃতি: আমি যা বর্ণনা করেছি তা হ'ল ম্যালোকের একটি সাধারণ বাস্তবায়ন, তবে কোনওভাবেই সম্ভব নয়।


12

আপনার স্ট্রাইকপি লাইনটি এনএলএল টার্মিনেটরের কারণে 9 টি নয়, 9 বাইট সঞ্চয় করার চেষ্টা করে। এটি অনির্ধারিত আচরণকে আহ্বান করে।

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

একটি ডিবাগিং-স্টাইলের মেমরি বরাদ্দকারী সহ, আপনি দেখতে পাবেন যে সেখানে একটি বিশেষ গার্ডের মান লেখা হয়েছে, এবং সেই মান এবং প্যানিকগুলি যদি এটি খুঁজে না পায় তবে এটি বিনামূল্যে পরীক্ষা করে।

অন্যথায়, আপনি দেখতে পাবেন যে পরবর্তী 5 বাইটে মেমরির অন্য কোনও ব্লকের অন্তর্ভুক্ত লিঙ্ক নোডের অংশ রয়েছে যা এখনও বরাদ্দ করা হয়নি। আপনার ব্লকটি মুক্ত করা এটি উপলব্ধ ব্লকগুলির তালিকায় যুক্ত হওয়া ভালভাবে জড়িত থাকতে পারে এবং আপনি তালিকা নোডে লিখেছেন যে ক্রিয়াকলাপটি একটি অবৈধ মান সহ একটি পয়েন্টারকে অবজ্ঞা করতে পারে।

এটি সমস্ত মেমরি বরাদ্দকারী উপর নির্ভর করে - বিভিন্ন বাস্তবায়ন বিভিন্ন প্রক্রিয়া ব্যবহার করে।


12

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

Malloc () দ্বারা বরাদ্দ করা মেমরির ব্লকটি অতীত লিখে আপনি সম্ভবত পরবর্তী ব্লকের কিছু বই-রক্ষিত তথ্য নষ্ট করবেন যা মেমরির অবশিষ্ট অব্যবহৃত ব্লক হতে পারে।

বাফারে অনেকগুলি অক্ষর অনুলিপি করার সময় আপনি যেখানে প্রোগ্রামটি ক্র্যাশ করতে পারেন সেখানকার একটি জায়গা। অতিরিক্ত অক্ষরগুলি স্তূপের বাইরে অবস্থিত থাকলে আপনি অ-বিদ্যমান মেমোরিতে লেখার চেষ্টা করার কারণে আপনি অ্যাক্সেস লঙ্ঘন পেতে পারেন।


6

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


5

malloc এবং বিনামূল্যে বাস্তবায়ন নির্ভর are একটি সাধারণ প্রয়োগের মধ্যে উপলভ্য মেমরিটিকে একটি "ফ্রি তালিকায়" বিভক্ত করা - উপলব্ধ মেমরি ব্লকের একটি লিঙ্কযুক্ত তালিকা। অনেকগুলি বাস্তবায়ন কৃত্রিমভাবে এটিকে ছোট বনাম বড় বস্তুগুলিতে বিভক্ত করে। ফ্রি ব্লকগুলি মেমরি ব্লকটি কত বড় এবং পরবর্তীটি কোথায় থাকে ইত্যাদি সম্পর্কিত তথ্য দিয়ে শুরু হয় etc.

আপনি malloc যখন, একটি তালিকা ফ্রি তালিকা থেকে টানা হয়। আপনি মুক্ত করার পরে, ব্লকটি ফ্রি তালিকায় আবার ফেলা হয়। সম্ভাবনাগুলি হ'ল, আপনি যখন আপনার পয়েন্টারের শেষটি ওভাররাইট করবেন তখন আপনি ফ্রি তালিকার একটি ব্লকের শিরোনামে লিখছেন। আপনি যখন আপনার স্মৃতি মুক্ত করেন, নিখরচায় () পরবর্তী ব্লকটি দেখার চেষ্টা করে এবং সম্ভবত কোনও পয়েন্টারটিকে আঘাত করে যা একটি বাসের ত্রুটির কারণ হয়ে দাঁড়ায়।


4

ঠিক আছে এটি মেমরির বরাদ্দকরণের বাস্তবায়ন এবং ওএসের উপর নির্ভর করে।

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

ফ্রি তখন শিরোনামটি সরিয়ে ফ্রি মেমরি তালিকায় এটি আবার যুক্ত করবে। যদি এটি আশেপাশের ফ্রি ব্লকগুলির সাথে একটি বৃহত ব্লক গঠন করে তবে এগুলি আরও বড় ব্লক দেওয়ার জন্য যুক্ত করা হবে। যদি একটি সম্পূর্ণ পৃষ্ঠা এখন বিনামূল্যে থাকে তবে বরাদ্দকারী সম্ভবত পৃষ্ঠায় ওএস এ ফিরে আসবে।

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

সম্পাদনা করুন: বরাদ্দের চেয়ে বড় লিখে আপনি পরবর্তী মেমরি শিরোনামটি ওভাররাইট করেছেন এই কারণে আপনার ক্রাশ হবে। এইভাবে যখন এটি মুক্ত হয় তখন এটি ঠিক কী নিখরচায় হয় এবং কীভাবে নীচের ব্লকে একীভূত হয় তা খুব বিভ্রান্ত হয়। এটি সর্বদা বিনামূল্যে সরাসরি ক্রাশের কারণ নাও হতে পারে। এটি পরে ক্রাশ হতে পারে। সাধারণভাবে এড়িয়ে চলুন স্মৃতি ওভাররাইট!


3

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

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

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

2

এটি বলা শক্ত কারণ প্রকৃত আচরণ বিভিন্ন সংকলক / রানটাইমের মধ্যে আলাদা। এমনকি ডিবাগ / রিলিজ বিল্ডগুলিরও আলাদা আচরণ রয়েছে। VS2005 এর ডিবাগ বিল্ডগুলি মেমরির দুর্নীতি সনাক্ত করতে বরাদ্দগুলির মধ্যে চিহ্নিতকারী প্রবেশ করিয়ে দেবে, সুতরাং ক্রাশের পরিবর্তে এটি নিখরচায় () ফোকাস করে।


1

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

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