ওয়ান-আর্গুমেন্ট free(void *)
(ইউনিক্স ভি 7 তে প্রবর্তিত) এর আগের দুটি-যুক্তির চেয়ে আরও একটি বড় সুবিধা রয়েছে mfree(void *, size_t)
যা আমি এখানে উল্লেখ করি নি: একটি যুক্তি free
নাটকীয়ভাবে প্রতিটি অন্যান্য এপিআইকে সহজতর করে যা হ্যাপ মেমরির সাথে কাজ করে । উদাহরণস্বরূপ, যদি free
মেমরি ব্লকের আকারের প্রয়োজন হয় strdup
তবে কোনওভাবে এক (পয়েন্টার) এর পরিবর্তে দুটি মান (পয়েন্টার + আকার) প্রদান করতে হবে, এবং সি একক মানের রিটার্নের তুলনায় একাধিক মানের রিটার্নকে আরও জটিল করে তুলবে। পরিবর্তে char *strdup(char *)
আমাদের লিখতে হবে char *strdup(char *, size_t *)
অন্যথায় struct CharPWithSize { char *val; size_t size}; CharPWithSize strdup(char *)
। (আজকাল সেই দ্বিতীয় বিকল্পটি বেশ লোভনীয় বলে মনে হচ্ছে, কারণ আমরা জানি যে NUL- সমাপ্ত স্ট্রিংগুলিই "কম্পিউটিংয়ের ইতিহাসের সবচেয়ে বিপর্যয়কর নকশা বাগ", কিন্তু এটি হিন্দ্দৃষ্টি বলছে। 70 এর দশকে ফিরে, সি হিসাবে স্ট্রিংগুলিকে সাধারণ হিসাবে পরিচালনা করার ক্ষমতা char *
আসলে প্যাসকেল এবং আলগোলের মতো প্রতিযোগীদের তুলনায় একটি সংজ্ঞায়িত সুবিধা হিসাবে বিবেচিত হয়েছিল ।) এছাড়াও, এটি কেবল strdup
এই সমস্যায় ভুগছে না - এটি প্রতিটি সিস্টেমকে প্রভাবিত করে - বা ব্যবহারকারী-সংজ্ঞায়িত ফাংশন যা হিপ মেমরি বরাদ্দ করে।
প্রারম্ভিক ইউনিক্স ডিজাইনাররা খুব চালাক লোক ছিলেন এবং মূলত এর free
চেয়ে আরও ভাল কারণগুলির অনেক কারণ রয়েছে বলে mfree
আমি মনে করি প্রশ্নের উত্তরটি হ'ল তারা এটিকে লক্ষ্য করেছে এবং সেই অনুযায়ী তাদের সিস্টেমটি ডিজাইন করেছে। আমি সন্দেহ করি যে তারা এই সিদ্ধান্ত নেওয়ার মুহুর্তে তাদের মাথার ভিতরে কী চলছে তার সরাসরি কোনও রেকর্ড পাবেন। তবে আমরা কল্পনা করতে পারি।
ভান করুন যে আপনি সি-তে অ্যাপ্লিকেশনগুলি ভি-ইউনিক্সে চালানোর জন্য তার দ্বি-যুক্তির সাথে লিখছেন mfree
। আপনি এখন পর্যন্ত ঠিকঠাক ব্যবস্থাপন করেছেন, তবে আপনার প্রোগ্রামগুলি আরও উচ্চাভিলাষী হয়ে ওঠার জন্য এবং এই স্তরের বরাদ্দক ভেরিয়েবলগুলির আরও এবং বেশি ব্যবহারের প্রয়োজন হওয়ায় এই পয়েন্টার মাপগুলিকে ট্র্যাক করা আরও বেশি ঝামেলা হয়ে উঠছে । তবে তারপরে আপনার কাছে একটি উজ্জ্বল ধারণা রয়েছে: এইগুলি size_t
সর্বদা অনুলিপি করার পরিবর্তে আপনি কিছু কিছু ইউটিলিটি ফাংশন লিখতে পারেন যা আকার বরাদ্দকৃত মেমরির ভিতরে সরাসরি স্ট্যাশ করে:
void *my_alloc(size_t size) {
void *block = malloc(sizeof(size) + size);
*(size_t *)block = size;
return (void *) ((size_t *)block + 1);
}
void my_free(void *block) {
block = (size_t *)block - 1;
mfree(block, *(size_t *)block);
}
এবং এই নতুন ফাংশনগুলি ব্যবহার করে আপনি যত বেশি কোড লিখবেন তত বেশি ভয়ঙ্কর বলে মনে হয়। তারা শুধুমাত্র লিখতে আপনার কোড সহজ করতে, তারা এছাড়াও আপনার কোড করা দ্রুততর - দুটি জিনিস যা প্রায়ই একসঙ্গে যাবেন না! আপনি size_t
পুরো স্থান জুড়ে এইগুলি পাস করার আগে , যা অনুলিপি করার জন্য সিপিইউ ওভারহেড যুক্ত করেছিল এবং এর অর্থ হল আপনাকে আরও প্রায়ই নিবন্ধগুলি ছড়িয়ে দিতে হয়েছিল (উদাহরণস্বরূপ অতিরিক্ত ফাংশন যুক্তির জন্য), এবং নষ্ট স্মৃতি (যেহেতু নেস্টেড ফাংশন কলগুলি প্রায়শই ফলস্বরূপ ঘটবে) size_t
বিভিন্ন স্ট্যাক ফ্রেমে সংরক্ষণের একাধিক অনুলিপিগুলিতে )। আপনার নতুন সিস্টেমে, আপনার এখনও স্টোর সঞ্চয় করতে মেমরিটি ব্যয় করতে হবেsize_t
, তবে কেবল একবার, এবং এটি কোথাও কখনও অনুলিপি করা হয় না। এগুলি ছোট দক্ষতার মতো মনে হতে পারে তবে মনে রাখবেন যে আমরা 256 কিবি র্যামের উচ্চতা সম্পন্ন মেশিনগুলির বিষয়ে কথা বলছি।
এটি আপনাকে খুশি করে! সুতরাং আপনি দাড়িওয়ালা পুরুষদের সাথে আপনার দুর্দান্ত কৌশলটি ভাগ করেছেন যারা পরের ইউনিক্স রিলিজে কাজ করছেন, তবে এটি তাদের খুশি করে না, এটি দুঃখ করে তোলে। আপনি দেখুন, তারা ঠিক যেমন নতুন কিছু ইউটিলিটি ফাংশন যুক্ত করার প্রক্রিয়ায় ছিল strdup
এবং তারা বুঝতে পেরেছিল যে আপনার শীতল কৌশল ব্যবহার করে লোকেরা তাদের নতুন ফাংশনগুলি ব্যবহার করতে সক্ষম হবে না, কারণ তাদের নতুন ফাংশনগুলি সবগুলি বোঝার পয়েন্টার + আকার ব্যবহার করে এপিআই এবং তারপরে এটি আপনাকেও দু: খিত করে তোলে, কারণ আপনি বুঝতে পেরেছেন strdup(char *)
যে সিস্টেম সংস্করণটি ব্যবহার করতে সক্ষম না হয়ে নিজের লেখার প্রতিটি প্রোগ্রামে আপনাকে নিজের ভাল ফাংশনটি আবার লিখতে হবে।
কিন্তু অপেক্ষা করো! এটি 1977, এবং পিছনে সামঞ্জস্যতা আরও 5 বছরের জন্য আবিষ্কার করা হবে না! আর তাছাড়া কেউ গুরুতর আসলে ব্যবহার তার ফেকাসে নাম দিয়ে এই অস্পষ্ট "ইউনিক্স" জিনিস। কেএন্ডআর-এর প্রথম সংস্করণটি এখন প্রকাশকের কাছে চলেছে, তবে এটি কোনও সমস্যা নয় - এটি প্রথম পৃষ্ঠায় সরাসরি বলেছে যে "সি অক্ষরযুক্ত স্ট্রিংয়ের মতো সংমিশ্রিত বস্তুগুলির সাথে সরাসরি ডিল করার জন্য কোনও ক্রিয়াকলাপ সরবরাহ করে না ... কোনও গাদা নেই is ... "। ইতিহাসের এই মুহুর্তে string.h
এবং malloc
এটি বিক্রেতার এক্সটেনশন (!)। সুতরাং, দাড়িওয়ালা ম্যান # 1 এর পরামর্শ দেয়, আমরা তাদের পছন্দমতো পরিবর্তন করতে পারি; কেন আমরা কেবলমাত্র আপনার ছদ্মবেশী বরাদ্দকারীকে সরকারী বরাদ্দকারী হিসাবে ঘোষণা করি না ?
কিছু দিন পরে, দাড়িওয়ালা ম্যান # 2 নতুন এপিআই দেখে এবং বলে ওহে, অপেক্ষা কর, এটি আগের চেয়ে ভাল, তবে এটি এখনও বরাদ্দের জন্য পুরো শব্দটি আকার সংরক্ষণ করে ব্যয় করে। তিনি এটিকে নিন্দা করার পরবর্তী বিষয় হিসাবে দেখেন। সবাই তার দিকে তাকাচ্ছে যেমন সে পাগল, কারণ আপনি আর কী করতে পারেন? সে রাতে তিনি দেরি করে থাকেন এবং একটি নতুন বরাদ্দকারী আবিষ্কার করেন যা আকারটি মোটেও সংরক্ষণ করে না, তবে পরিবর্তে এটি পয়েন্টার মানের উপরে কালো যাদু বিটশিফ্ট সম্পাদন করে ফ্লাইতে অনুপ্রবেশ করে এবং নতুন এপিআই রাখার সময় এটিকে অদলবদল করে। নতুন এপিআইটির অর্থ হ'ল কেউই স্যুইচটি লক্ষ্য করে না, তবে তারা লক্ষ্য করে যে পরের দিন সকালে সংকলকটি 10% কম র্যাম ব্যবহার করে।
এবং এখন সকলেই খুশি: আপনি আপনার সহজেই লেখার সহজ এবং দ্রুত কোডটি পান, দাড়িওয়ালা ম্যান # 1 একটি দুর্দান্ত সহজ লিখতে পেল strdup
যা লোকেরা আসলে ব্যবহার করবে, এবং দাড়িওয়ালা ম্যান # 2 - তিনি আত্মবিশ্বাসী যে তিনি কিছুটা সময় রেখেছিলেন - - কুইন্সের সাথে ঘোরাঘুরি করতে ফিরে যায় । শিপ!
বা কমপক্ষে, এটি ঘটতে পারে কিভাবে ।