কীভাবে ফ্রি জানবে কতটা ফ্রি করতে হবে?


384

সি প্রোগ্রামিংয়ে আপনি যে কোনও প্রকারের পয়েন্টারকে বিনামূল্যে আর্গুমেন্ট হিসাবে পাস করতে পারেন, কীভাবে এটি বরাদ্দ মেমরির আকারটি বিনামূল্যে জানবে? আমি যখনই কোনও ফাংশনে একটি পয়েন্টারটি পাস করি তখন আমাকে আকারটিও পাস করতে হবে (অর্থাত অ্যারের আকার জানতে 10 প্যারামিটার হিসাবে 10 টি উপাদানের একটি অ্যারে প্রয়োজন 10) তবে আমাকে আকারটি পাস করতে হবে না বিনামূল্যে ফাংশন। কেন নয়, এবং অ্যারের দৈর্ঘ্যের অতিরিক্ত ভেরিয়েবলের চারপাশে আমাকে কার্ট লাগানো থেকে বাঁচাতে আমি নিজের ফাংশনে এই একই কৌশলটি ব্যবহার করতে পারি?


একটি অনুরূপ প্রশ্ন: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 19৮৯৫৫ / / ((যদিও আমি বলি এটি একেবারেই নকল নয়)
জন কার্টার

বন্ধুকে সিস্টেম এটা করতে অন্য উপায় যে পয়েন্টার উপর ভিত্তি করে চিন্তা করতে পারেন, প্রতিটি ব্লকে ওভারহেড ছাড়া হয়।
এভিলটিচ

এই পোস্টটি এটি ভালভাবে ব্যাখ্যা করেছে: stackoverflow.com/questions/1957099/…
জিশান মাহমুদ

উত্তর:


348

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

আপনি যখন কল করবেন তখন free()ব্লকটি কতটা বড় তা সন্ধান করার জন্য এটি অতিরিক্ত তথ্যের দিকে নজর দেয়।


44
এফওয়াইআই, উদাহরণস্বরূপ, বিএসডি malloc_size()একটি malloc()এড পয়েন্টার থেকে ব্লকের আকারকে নির্ভরযোগ্যভাবে অ্যাক্সেস করতে হবে । তবে কোনও নির্ভরযোগ্য, বহনযোগ্য উপায় নেই।
laalto

50
আমি বলে মনে করি যে এটি অতিরিক্ত তথ্য ব্লকটি প্রত্যাবর্তিত পয়েন্টারের আগে অবস্থিত।
জর্জি স্কলি 8

39
@gs ভাল এটি বাস্তবায়ন নির্ভর। তবে, হ্যাঁ, এটি সাধারণত সেখানেই।
ফালাইনা

31
free()প্রোগ্রামারটিকে সঠিকভাবে malloc()ব্লকটি কতটা বড় ছিল তা রিপোর্ট করার জন্য যদি আপনি হররটি কল্পনা করতে পারেন ? মেমরি ফাঁস যেমন আছে তেমন খারাপ।
মুশিজেসিস 13

35
কেন সেই তথ্যটি পাওয়া যায় malloc()এবং free()তবে আপনাকে একটি অ্যারের আকার সংরক্ষণ করতে হবে? blockSize(ptr)তারা তথাপি যেভাবেই স্টোর করে রাখছে তবে কেন এমন কিছু করা সম্ভব হবে না ?
কর্সিকা

144

সি মেমরি বরাদ্দ ফাংশনগুলির বেশিরভাগ বাস্তবায়ন প্রতিটি ব্লকের জন্য অ্যাকাউন্টের তথ্য ইন-লাইন বা পৃথকভাবে সঞ্চয় করবে।

একটি সাধারণ উপায় (ইন-লাইন) হ'ল শিরোনাম এবং মেমরির জন্য আপনি যে ন্যূনতম আকারে প্যাড করেছেন তা উভয়ই বরাদ্দ করা। সুতরাং উদাহরণস্বরূপ, আপনি যদি 20 বাইট চেয়েছিলেন, সিস্টেমটি 48-বাইট ব্লক বরাদ্দ করতে পারে:

  • আকার, বিশেষ চিহ্নিতকারী, চেকসাম, পরবর্তী / পূর্ববর্তী ব্লকের পয়েন্টার এবং এগুলি সহ 16 বাইট শিরোনাম
  • 32 বাইট ডেটা আয়তন (আপনার 20 বাইট 16 এর একাধিকতে প্যাড করেছে)।

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

 ____ The allocated block ____
/                             \
+--------+--------------------+
| Header | Your data area ... |
+--------+--------------------+
          ^
          |
          +-- The address you are given

শিরোনামের আকার এবং প্যাডিং পুরোপুরি বাস্তবায়ন সংজ্ঞায়িত করা মনে রাখবেন (আসলে, পুরো জিনিসটি বাস্তবায়ন-সংজ্ঞায়িত (ক) তবে ইন-লাইন অ্যাকাউন্টিং বিকল্পটি একটি সাধারণ)।

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

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


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

অন্যরা যেগুলির বিকাশ করেছি তাদের মধ্যে 16-বাইট খণ্ড, 64-বাইট খণ্ড, 256-বাইট খণ্ড এবং 1 কে খণ্ডগুলির জন্য আলাদা পুল রয়েছে, আবার কী কী ব্লক ব্যবহার করা হয়েছে বা উপলভ্য তা স্থির করতে বিট-মাস্ক ব্যবহার করে।

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


@ প্যাক্সিয়াব্লো এর অর্থ কী ম্যালোক মেমরির সংলগ্ন ব্লক বরাদ্দ করে না?
ব্যবহারকারী 10678

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

সম্পর্কিত প্রশ্ন: কেন ম্যালোক / ফ্রি এর কোনও পার্থক্য নেই, যেখানে আপনি মুক্ত করার সময় আকার নির্দিষ্ট করেন এবং এটি আকার সংরক্ষণ করতে হয় না?
ব্যবহারকারী 253751

@ user253751, কারণ তারপর এর theer এক আরো জিনিস তোমাদের, ওভার এবং পয়েন্টার নিজেই উপরে ট্র্যাক রাখতে প্রয়োজন। এটি অপ্রয়োজনীয় এবং বিপজ্জনক উভয়ই : ভালভাবে শেষ void *x = malloc(200); free(x, 500);হচ্ছে না :-) কোনও ক্ষেত্রেই, দক্ষতার জন্য, বাফারের আসল আকারটি আরও বড় হতে পারে (আপনি কেবল এটির উপর নির্ভর করতে পারবেন না)।
প্যাক্সিডিয়াবলো

@ প্যাক্সিয়াব্লো এটি আকার ধারণ করতে মেমরির অপচয় করাও এড়িয়ে যায়।
ব্যবহারকারী 253751

47

থেকে comp.lang.cপ্রায়শই জিজ্ঞাসিত প্রশ্নাবলী তালিকা: কিভাবে বিনামূল্যে জানি কত বাইট মুক্ত করতে না?

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


2
এটি একটি উত্তর নেই। প্রশ্নটি হ'ল: নিখরচায় কেন ব্লকের আকারটি নিখরচায় দেখতে পারা যায়, তবে প্রোগ্রামারের কাছে এমন কোনও ফাংশন নেই যা তা করে?
কলাচ

এটি প্রকৃতপক্ষে ম্যালোক এপিআই-র জন্য একটি বাস্তবায়নের বিশদ এবং মানক উপায়ে (আমার জ্ঞানের কাছে) এই তথ্য ফিরে পেতে কোনও এপিআই নেই। "সিস্টেম" এটি রেকর্ড করে এবং এটি ব্যবহার করে free। হয়তো উত্তরটি আপনাকে সন্তুষ্ট করছে না তবে আমি মনে করি না যে আপনি আরও সাধারণভাবে প্রযোজ্য তথ্যের সাথে একটি পাবেন :-)
jdehaan

6

এই উত্তরটি স্থানান্তরিত হয়েছে কীভাবে ফ্রি () কীভাবে জানতে পারে যে মেমরিটি হ্রাস করতে হবে? যেখানে আমাকে আপত্তিজনকভাবে সদৃশ সদৃশ প্রশ্নের দ্বারা উত্তর দিতে বাধা দেওয়া হয়েছিল। এই উত্তরটি তখন এই সদৃশটির সাথে প্রাসঙ্গিক হওয়া উচিত:


এর ক্ষেত্রে malloc, হিপ বরাদ্দকারী freeমেমরিটি পরে ফিরে আসার জন্য প্রয়োজনীয় রিটার্ন পয়েন্টারটির ম্যাপিং সংরক্ষণ করে । এর মধ্যে সাধারণত বরাদ্দকারীর ব্যবহারের ক্ষেত্রে প্রাসঙ্গিক যে কোনও আকারে মেমরি অঞ্চলের আকার সংরক্ষণ করা জড়িত, উদাহরণস্বরূপ কাঁচা আকার, বা বরাদ্দগুলি ট্র্যাক করতে ব্যবহৃত বাইনারি গাছের নোড বা ব্যবহৃত মেমরির "ইউনিট" একটি গণনা।

freeআপনি যদি পয়েন্টারটির "নাম পরিবর্তন" করেন বা কোনওভাবেই এটি সদৃশ করেন তবে ব্যর্থ হবে না। এটি রেফারেন্স গণনা করা হয় না, এবং শুধুমাত্র প্রথম freeসঠিক হবে। অতিরিক্ত freeগুলি হ'ল "ডাবল ফ্রি" ত্রুটি।

freeপূর্বের mallocs দ্বারা প্রত্যাবর্তনকারীদের চেয়ে আলাদা মানের সাথে কোনও পয়েন্টারের চেষ্টা করা এবং এখনও অব্যুক্ত হওয়া ত্রুটি। আংশিক মুক্ত মেমরি অঞ্চলগুলি থেকে ফিরে আসা সম্ভব নয় malloc


আমি ম্যালোক কল দিয়ে ফিরে আসা পয়েন্টারের মান পরিবর্তন করেছি। এবং আমি এটিকে ত্রুটি ছাড়াই মুক্তি দিয়েছি। কেন? এখানে দেখুন: stackoverflow.com/questions/42618390/...
smwikipedia

4

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


3

malloc()এবং free()সিস্টেম / সংকলক নির্ভরশীল তাই নির্দিষ্ট উত্তর দেওয়া শক্ত।

এই অন্যান্য প্রশ্নে আরও তথ্য ।


2
তারা প্রকৃতপক্ষে গ্রন্থাগার-নির্ভর (সাধারণত সি গ্রন্থাগার, যা সাধারণত ওএসের সাথে খুব ঘনিষ্ঠভাবে সংযুক্ত থাকে)। সংকলক, তারা কেবল ফাংশন।
ডোনাল ফেলো

2

আপনি কল করার সময় হিপ ম্যানেজার বরাদ্দকৃত ব্লকের সাথে সম্পর্কিত মেমরির পরিমাণ সংরক্ষণ করে malloc

আমি নিজেই কোনওটিকে বাস্তবায়ন করি নি, তবে আমি অনুমান করি বরাদ্দকৃত ব্লকের সামনের মেমরিটিতে মেটা সম্পর্কিত তথ্য থাকতে পারে।


3
এটি একটি সম্ভাব্য বাস্তবায়ন, তবে একটি এমন একটি সিস্টেম তৈরি করতে পারে যেখানে সমস্ত মেমরি সম্পূর্ণ ভিন্ন পৃষ্ঠায় একক টেবিলে ট্র্যাক করা হয়, মেমরি পুলের কাছ থেকে বরাদ্দকৃত কোথাও খুব অগত্যা নয়।
পূর্ববর্তী

2

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

এই কৌশলগুলিতে কিছু সমস্যা রয়েছে যেমন, দুর্বল ক্যাশে এবং মেমরি পরিচালনার আচরণ। ব্লকের ডানদিকে স্মৃতি ব্যবহার করা অযৌক্তিকভাবে পৃষ্ঠাগুলির দিকে ঝোঁকায় এবং এটি নোংরা পৃষ্ঠাগুলিও তৈরি করে যা ভাগ করে নেওয়া এবং অনুলিখনকে জটিল করে তোলে ate

সুতরাং আরও উন্নত কৌশল হ'ল পৃথক ডিরেক্টরি রাখা। বিদেশী দৃষ্টিভঙ্গিগুলিও বিকাশ করা হয়েছে যেখানে মেমরির ক্ষেত্রগুলি দুটি পাওয়ার আকারের একই শক্তি ব্যবহার করে use

সাধারণভাবে, উত্তরটি হ'ল: রাষ্ট্র ধরে রাখতে আলাদা তথ্য কাঠামো বরাদ্দ করা হয়।


1

আপনার প্রশ্নের দ্বিতীয়ার্ধের উত্তর দিতে: হ্যাঁ, আপনি পারবেন, এবং সিতে মোটামুটি সাধারণ প্যাটার্নটি নিম্নলিখিত:

typedef struct {
    size_t numElements
    int elements[1]; /* but enough space malloced for numElements at runtime */
} IntArray_t;

#define SIZE 10
IntArray_t* myArray = malloc(sizeof(intArray_t) + SIZE * sizeof(int));
myArray->numElements = SIZE;

এটি বিএসডি ম্যালোকের ছোট জিনিসগুলির জন্য ব্যবহৃত একের সম্পূর্ণ ভিন্ন কৌশল (যদিও এটি পাস্কাল স্টাইল অ্যারে তৈরির জন্য একেবারে ভাল কৌশল)
পিট কির্খাম

0

আমরা যখন মলোককে কল করি তখন এটি প্রয়োজন থেকে আরও বাইট ব্যবহার করে consume এই আরও বাইট ব্যবহারে চেক সমষ্টি, আকার এবং অন্যান্য অতিরিক্ত তথ্য সম্পর্কিত তথ্য থাকে। আমরা যখন ফ্রি কল করি তখন এটি সরাসরি সেই অতিরিক্ত তথ্যে যায় যেখানে এটি ঠিকানাটি খুঁজে পায় এবং এটিও জানতে পারে যে কতটা ব্লক মুক্ত থাকবে।


0

দ্বিতীয় প্রশ্নের উত্তর দেওয়ার জন্য, হ্যাঁ আপনি (ধরণের) ঠিক একই কৌশলটি ব্যবহার করতে পারবেন ঠিক যেমন malloc() অ্যারের আকারের জন্য প্রতিটি অ্যারের অভ্যন্তরে প্রথম ঘরটি নির্ধারণ করে। এটি আপনাকে অতিরিক্ত আকারের যুক্তি না পাঠিয়ে অ্যারে পাঠাতে দেয়।

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