ম্যালোক এবং কলোকের মধ্যে পার্থক্য?


779

করার মধ্যে পার্থক্য কি:

ptr = (char **) malloc (MAXELEMS * sizeof(char *));

বা:

ptr = (char **) calloc (MAXELEMS, sizeof(char*));

ম্যালোক বা বিপরীতে কলোক ব্যবহার করা কখন ভাল ধারণা?



8
সি তে, আপনি উপরের দিক থেকে আরও সাধারণভাবে লিখতে পারেন:ptr = calloc(MAXELEMS, sizeof(*ptr));
chqrlie


2
@dddavidee আমিও ব্লগটি নেটটিতে এতগুলি উত্তর নিয়ে অসন্তুষ্ট হওয়ার পরে পেয়েছি। নাথানিয়েল জে স্মিথ তার বিশ্লেষণের জন্য 100+ এসও পয়েন্টের দাবিদার।
লাইফব্লেন্স 14

উত্তর:


849

calloc()আপনাকে একটি শূন্য-আরম্ভের বাফার দেয়, যখন malloc()স্মৃতিটিকে অবিচ্ছিন্ন করে দেয়।

বড় বরাদ্দের জন্য, callocমূলধারার ওএসের অধীনে বেশিরভাগ বাস্তবায়নগুলি ওএস থেকে জ্ঞাত-শূন্য পৃষ্ঠাগুলি পাবেন (যেমন পসিক্স mmap(MAP_ANONYMOUS)বা উইন্ডোজ মাধ্যমে VirtualAlloc) সুতরাং এটি ব্যবহারকারী-স্পেসে লেখার দরকার নেই। এইভাবে mallocওএস থেকেও আরও সাধারণ পৃষ্ঠা পাওয়া যায়; callocকেবল ওএসের গ্যারান্টির সুযোগ নেয়।

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

কিছু সংকলক এমনকি ম্যালোক + মেমসেট (0) আপনার জন্য কলকে অপ্টিমাইজ করতে পারে, তবে আপনি যদি মেমরিটি পড়তে চান তবে আপনার স্পষ্টভাবে কলোক ব্যবহার করা উচিত 0

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


এর এম্বেড থাকা বাস্তবায়নগুলি যদি ওএস না থাকে তবে callocএটি callocশূন্য মেমরির কাছে ছেড়ে দিতে পারে বা প্রক্রিয়াগুলির মধ্যে তথ্য ফাঁস বন্ধ করতে পৃষ্ঠাগুলি শূন্য করে এমন কোনও অভিনব মাল্টি-ইউজার ওএস নয়।

এম্বেড থাকা লিনাক্সে, malloc পারে mmap(MAP_UNINITIALIZED|MAP_ANONYMOUS), যা কেবলমাত্র কিছু এম্বেড থাকা কার্নেলের জন্য সক্ষম কারণ এটি বহু-ব্যবহারকারী সিস্টেমে সুরক্ষিত নয়।


224
* বরাদ্দের রূপগুলি খুব স্মরণীয় - পরিষ্কার-বরাদ্দ, মেমরি-বরাদ্দ, পুনরায় বরাদ্দ।
ক্যাসকেবেল

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

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

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

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

362

একটি কম পরিচিত পার্থক্য হ'ল লিনাক্সের মতো আশাবাদী মেমরি বরাদ্দকরণ সহ অপারেটিং সিস্টেমগুলিতে, mallocপ্রোগ্রামটি এটি স্পর্শ না করা অবধি পয়েন্টারটি রিয়েল মেমরি দ্বারা ব্যাক হয় না।

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

ম্যালোকের আচরণ সম্পর্কে আরও আলোচনার জন্য উদাহরণস্বরূপ এই এসও প্রশ্নটি দেখুন


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

3
@ আর .. আকর্ষণীয় নোট। কিন্তু বাস্তবে, বন্যের মধ্যে কি এই ধরনের বাস্তবায়ন বিদ্যমান?
ইসাক সাভো

10
সকল dlmalloc-একটি বাস্তবায়নের লাফালাফি memsetযদি খণ্ড মাধ্যমে প্রাপ্ত হয়েছিল mmapনতুন বেনামী পৃষ্ঠাগুলি ing (অথবা সমতুল্য)। সাধারণত 256k বা আরও কিছুক্ষণ ধরে এই ধরণের বরাদ্দ বৃহত্তর অংশগুলির জন্য ব্যবহৃত হয়। আমি নিজের কাছ থেকে শূন্য লেখার আগে শূন্যের তুলনায় তুলনা করে এমন কোনও বাস্তবায়ন জানি না।
আর .. গীটহাব বন্ধ করুন ICE

1
omallocএছাড়াও অগ্রাহ্য memset; callocইতিমধ্যে অ্যাপ্লিকেশন (পৃষ্ঠা ক্যাশে) ইতিমধ্যে ব্যবহার করা হয়নি এমন কোনও পৃষ্ঠাকে স্পর্শ করার দরকার নেই। যদিও, চরম আদিম callocপ্রয়োগগুলি পৃথক।
মীরাবিলোস

10
গ্লিবসি-এর কলোকটি ওএস থেকে নতুন স্মৃতি পেয়ে থাকলে তা পরীক্ষা করে। যদি তা হয় তবে এটি জানে যে এটি লেখার দরকার নেই, কারণ এমএমএপ (..., MAP_ANONYMOUS) ইতিমধ্যে শূন্য হওয়া মেমরিটি ফিরে আসে।
পিটার কর্ডস

111

এর প্রায়শই অবহেলিত সুবিধা callocহ'ল (এর যথাযথ বাস্তবায়ন) এটি আপনাকে পূর্ণসংখ্যার ওভারফ্লো দুর্বলতার বিরুদ্ধে রক্ষা করতে সহায়তা করবে। তুলনা করা:

size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);

বনাম

size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);

প্রাক্তন এর countচেয়ে বেশি হলে একটি ছোট বরাদ্দ এবং পরবর্তী বাফার ওভারফ্লোতে পরিণতি পেতে পারে SIZE_MAX/sizeof *bar। পরেরটি স্বয়ংক্রিয়ভাবে এই ক্ষেত্রে ব্যর্থ হবে যেহেতু বৃহত্তর কোনও বস্তু তৈরি করা যায় না।

অবশ্যই আপনাকে অ-কনফরম্যান্ট বাস্তবায়নগুলির দিকে নজর রাখতে হবে যা কেবলমাত্র ওভারফ্লো হওয়ার সম্ভাবনাটিকে উপেক্ষা করে ... যদি আপনি যে প্ল্যাটফর্মগুলি লক্ষ্য করেন এটি যদি উদ্বেগের বিষয় হয় তবে আপনাকে যাইহোক ওভারফ্লোর জন্য একটি ম্যানুয়াল পরীক্ষা করতে হবে।


17
স্পষ্টতই গাণিতিক ওভারফ্লো 2002 এর মধ্যে ওপেনএসএসএইচ গর্তের কারণ হয়েছিল memory মেমরি সম্পর্কিত ফাংশনগুলির সাথে এর বিপদগুলি সম্পর্কে ওপেনবিএসডি থেকে ভাল নিবন্ধ: undeadly.org/cgi?action=article&sid=20060330071917
ফিলিপ পি

4
@ কমরেডপি: আকর্ষণীয়। দুঃখের বিষয় আপনি যে নিবন্ধটি সংযুক্ত করেছেন তার শুরুতে ভুল তথ্য রয়েছে। সঙ্গে উদাহরণস্বরূপ charহয় না একটি ওভারফ্লো বরং একটি বাস্তবায়ন-সংজ্ঞায়িত রূপান্তর যখন একটি মধ্যে ফলাফলের পিছনে বরাদ্দ charঅবজেক্ট।
আর .. গীটহাব বন্ধ করুন ICE

এটি সম্ভবত উদাহরণের উদ্দেশ্যে রয়েছে। কারণ সংকলক সম্ভবত যেভাবেই এটি অপ্টিমাইজ করতে পারে। খনি এই asm মধ্যে সংকলন: 1 টিপুন
ফিলিপ পি।

1
@ ত্রিস্টোপিয়া: মূল বিষয়টি এই নয় যে কোডটি সমস্ত প্রয়োগের ক্ষেত্রে ব্যবহারযোগ্য, তবে অতিরিক্ত অনুমান ছাড়াই এটি ভুল এবং এইভাবে সঠিক / বহনযোগ্য ব্যবহার নয়।
আর .. গীটহাব বন্ধ করুন ICE

3
@ ত্রিস্টোপিয়া: যদি আপনার চিন্তাভাবনাটি " size_t64-বিট হয় তবে কোনও সমস্যা নেই", এটি নিরাপত্তা বাগের দিকে নিয়ে যাওয়ার চিন্তাভাবনার একটি ত্রুটিযুক্ত উপায়। size_tএকটি বিমূর্ত যে ধরনের মাপ প্রতিনিধিত্ব করে আর সেখানে একটি 32 বিট নম্বর এবং একটি স্বেচ্ছাচারী পণ্যের মনে কোনো কারণ হয় size_t(দ্রষ্টব্য: sizeof *barনীতিগতভাবে 64-বিট সি বাস্তবায়নে বেশি 2 ^ 32 হতে পারে!) মধ্যে ফিট করে size_t
আর .. গীটহাব স্টপ হেল্পিং আইসিসি

37

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

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

বিষয়টি সম্পর্কে এখানে একটি অপ্টিমাইজেশন গল্প রয়েছে: http://blogs.fau.de/hager/2007/05/08/benchmarking-fun-with-calloc-and-zero-pages/


26

বরাদ্দ হওয়া মেমরি ব্লকের আকারের মধ্যে কোনও পার্থক্য নেই। callocশারীরিক অল-শূন্য-বিটস প্যাটার্ন দিয়ে মেমরি ব্লকটি কেবল পূরণ করে। অনুশীলনে প্রায়শই এটি ধরে নেওয়া হয় যে মেমরি ব্লকের মধ্যে বরাদ্দকৃত callocঅবজেক্টগুলির প্রাথমিক অর্থ রয়েছে যেমন সেগুলি আক্ষরিক সাথে আরম্ভ করা হয়েছিল 0, অর্থাত্ পূর্ণসংখ্যার মান 0, ভাসমান-পয়েন্ট ভেরিয়েবলের - মান 0.0, পয়েন্টার - যথাযথ নাল পয়েন্টার মান থাকতে হবে , ইত্যাদি।

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

পরবর্তীতে, C99 স্ট্যান্ডার্ডে কারিগরি কর্পিজেন্ডের একটিতে, আচরণটি সমস্ত সংখ্যার ধরণের (যা অর্থবোধ করে) জন্য সংজ্ঞায়িত করা হয়েছিল। অর্থাৎ আনুষ্ঠানিকভাবে, বর্তমান সি ভাষায় আপনি calloc(এবং memset(..., 0, ...)) দিয়ে কেবল পূর্ণসংখ্যার প্রারম্ভিক করতে পারেন । সাধারণ ক্ষেত্রে অন্য যে কোনও কিছুর সূচনা করতে এটি সি ভাষার দৃষ্টিকোণ থেকে অপরিজ্ঞাত আচরণের দিকে পরিচালিত করে।

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

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


"অন্য গুরুত্বপূর্ণ বিবরণ" অনুচ্ছেদ অনুযায়ী: মনে হচ্ছে এটি memset(p, v, n * sizeof type);কোনও সমস্যার n * sizeof typeমুখোমুখি হয়েছে কারণ ওভারফ্লো হতে পারে। অনুমান করুন দৃ rob for(i=0;i<n;i++) p[i]=v;় কোডের জন্য আমার একটি লুপ ব্যবহার করতে হবে ।
chux - মনিকা পুনরায় ইনস্টল করুন

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

@chux না, যদি nউপাদানগুলির সাথে একটি অ্যারের উপস্থিত থাকে যেখানে একটি উপাদানের আকার থাকে sizeof typeতবে n*sizeof typeউপচে পড়া যায় না কারণ যে কোনও বস্তুর সর্বাধিক আকারের চেয়ে কম হওয়া উচিত SIZE_MAX
12431234123412341234123

@ 12431234123412341234123 একটি অ্যারের আকার সম্পর্কে সত্য <= SIZE_MAX, তবুও এখানে কোনও অ্যারে নেই। থেকে ফিরে পয়েন্টারটি calloc()বরাদ্দ মেমরির চেয়ে বেশি ছাড়িয়ে যেতে পারে SIZE_MAX। অনেক বাস্তবায়নের 2 args গুণফল সীমিত না calloc()থেকে SIZE_MAX, এখনো সি বৈশিষ্ট যে সীমা আরোপ করে না।
chux - মোনিকা

21

একটি নিবন্ধ থেকে () calloc সঙ্গে মজা মাপকাঠিতে এবং শূন্য পৃষ্ঠাগুলি উপর গেয়র্গ Hager এর ব্লগ

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


লিঙ্কটি কোথায়?
রূপেশ যাদব।

2
উত্তরের প্রথম লাইনে জর্জি হ্যাজারের ব্লগের লিঙ্ক রয়েছে।
আশীষ

11

callocসাধারণত malloc+memset0 হয়

সাধারণত malloc+memsetস্পষ্টভাবে ব্যবহার করা কিছুটা ভাল , বিশেষত আপনি যখন এমন কিছু করছেন:

ptr=malloc(sizeof(Item));
memset(ptr, 0, sizeof(Item));

এটি আরও ভাল কারণ sizeof(Item)সংকলনের সময় সংকলকটির জানা ছিল এবং সংকলক বেশিরভাগ ক্ষেত্রে শূন্য মেমরির সর্বোত্তম সম্ভাব্য নির্দেশাবলীর সাথে প্রতিস্থাপন করবে। অন্যদিকে যদি memsetঘটতে থাকে callocতবে বরাদ্দের প্যারামিটার আকারটি callocকোডে সংকলিত হয় না এবং রিয়েলকে memsetপ্রায়শই বলা হয়, যা সাধারণত চৌম্বকটি পূরণের চেয়ে দীর্ঘ সীমানা অবধি বাই বাই বাই পূরণ করতে কোড ধারণ করে would sizeof(long)খণ্ডগুলিতে মেমরি আপ এবং অবশেষে বাইট-বাই-বাইট অবশিষ্ট স্থান পূরণ করুন। এমনকি যদি কিছু বরাদ্দকারী কল করতে যথেষ্ট স্মার্ট হয় তবে aligned_memsetএটি এখনও জেনেরিক লুপ হবে।

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


এই অনুস্মারকটির জন্য +1 যে সিস্টেম লাইব্রেরিতে কার্যকারিতার জেনেরিক প্রয়োগটি ব্যবহারকারীর কোডে একই ক্রিয়াকলাপের চেয়ে অগত্যা দ্রুত নয়।
প্যাট্রিক Schlüter

1
দ্বিতীয় পয়েন্টটিও এর থেকে calloc()ধীর করে দেয় malloc(): আকারের জন্য গুণ lic calloc()জেনেরিক গুণটি ব্যবহার করা প্রয়োজন (যদি size_tb৪ বিট এমনকি অত্যন্ত ব্যয়বহুল b৪ বিট * b৪ বিট = b৪ বিট অপারেশন হয়) তবে ম্যালোক () প্রায়শই একটি সংকলনের সময় ধ্রুবক থাকে।
প্যাট্রিক Schlüter

4
ফিরে আসা অংশটিকে কীভাবে সবচেয়ে দক্ষতার সাথে পরিষ্কার করতে হয় তা নির্ধারণের জন্য গ্লিবসি কলোকের কিছু স্মার্ট রয়েছে, উদাহরণস্বরূপ, কখনও কখনও কেবলমাত্র এর অংশটি ক্লিয়ারিংয়ের প্রয়োজন হয়, এবং 9 * আকারের (সাইজ_টি) পর্যন্ত একটি নিয়ন্ত্রণহীন ক্লিয়ারও প্রয়োজন। মেমোরি হ'ল মেমরি, এটি একবারে 3 বাইট সাফ করা কেবল তত দ্রুত হয় না কারণ আপনি তখন এটি ধরে রাখতে ব্যবহার করছেন struct foo { char a,b,c; };। আপনি যদি সর্বদা পুরো এড অঞ্চলটি পরিষ্কার করতে থাকেন তবে + এর callocচেয়ে সর্বদা ভাল । আকার * উপাদানগুলিতেও খুব বেশি প্রবাহের জন্য একটি সাবধানে কিন্তু দক্ষ চেক রয়েছে। mallocmemsetmalloccalloc
পিটার কর্ডেস

8

পার্থক্য 1:

malloc() সাধারণত মেমরি ব্লক বরাদ্দ করে এবং এটি মেমরি বিভাগকে আরম্ভ করা হয়।

calloc() মেমরি ব্লক বরাদ্দ করে এবং সমস্ত মেমরি ব্লক 0 তে সূচনা করে।

পার্থক্য 2:

আপনি যদি malloc()সিনট্যাক্স বিবেচনা করেন তবে এটিতে কেবল 1 টি যুক্তি লাগবে। নীচের নীচের উদাহরণটি বিবেচনা করুন:

data_type ptr = (cast_type *)malloc( sizeof(data_type)*no_of_blocks );

উদাহরণস্বরূপ: আপনি যদি প্রকারের জন্য 10 টি মেমরির ব্লক বরাদ্দ করতে চান,

int *ptr = (int *) malloc(sizeof(int) * 10 );

আপনি যদি calloc()বাক্য গঠন বিবেচনা করেন তবে এটিতে 2 টি আর্গুমেন্ট লাগবে। নীচের নীচের উদাহরণটি বিবেচনা করুন:

data_type ptr = (cast_type *)calloc(no_of_blocks, (sizeof(data_type)));

উদাহরণস্বরূপ: আপনি যদি ইনট টাইপের জন্য 10 টি মেমরির ব্লক বরাদ্দ করতে চান এবং সেগুলি জিরোতে শুরু করতে চান,

int *ptr = (int *) calloc(10, (sizeof(int)));

মিল:

উভয় malloc()এবং calloc()কাস্ট করা টাইপ না করা হলে ডিফল্টরূপে বাতিল হয়ে যাবে *!


এবং আপনি কেন ডেটা টাইপ এবং কাস্ট_ টাইপ আলাদা রাখেন?
বিক্রি হয়েছে

7

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

  • calloc()একটি মেমরি অঞ্চল বরাদ্দ করে, দৈর্ঘ্যটি এর পরামিতিগুলির পণ্য হবে। callocজেরোর স্মৃতি পূরণ করে এবং প্রথম বাইটে একটি পয়েন্টার দেয়। এটি পর্যাপ্ত জায়গা সনাক্ত করতে ব্যর্থ হলে এটি একটি NULLপয়েন্টার দেয় returns

সিনট্যাক্স: ptr_var=(cast_type *)calloc(no_of_blocks , size_of_each_block); অর্থাৎptr_var=(type *)calloc(n,s);

  • malloc()রিকুইস্টেড সাইজের মেমরির একক ব্লক বরাদ্দ করে এবং প্রথম বাইটে একটি পয়েন্টার দেয়। যদি এটি মেমরির অবিশ্বস্ত পরিমাণ সনাক্ত করতে ব্যর্থ হয় তবে এটি একটি নাল পয়েন্টার দেয়।

শব্দবিন্যাস: ফাংশন, একটি আর্গুমেন্ট, যা বাইটের সংখ্যা বরাদ্দ নিতে যখন ফাংশন উপাদানের সংখ্যা হচ্ছে এক থেকে দুই আর্গুমেন্ট লাগে, এবং অন্যান্য বাইটের সংখ্যা যারা উপাদান প্রতিটি বরাদ্দ করা হচ্ছে। এছাড়াও, জিরোগুলিকে বরাদ্দ করা স্থানটি আরম্ভ করে, যখন তা করে না।ptr_var=(cast_type *)malloc(Size_in_bytes);malloc()calloc()calloc()malloc()


6

calloc()ফাংশন যা ঘোষণা করা হয় <stdlib.h>হেডার উপর সুবিধার দুয়েক উপলব্ধ করা হয় malloc()ফাংশন।

  1. এটি প্রদত্ত আকারের কয়েকটি উপাদান এবং হিসাবে মেমরির বরাদ্দ করে
  2. এটি বরাদ্দ করা মেমরিটিকে আরম্ভ করে যাতে সমস্ত বিট শূন্য হয়।

6

malloc()এবং calloc()সি স্ট্যান্ডার্ড লাইব্রেরির ফাংশন যা গতিশীল মেমরি বরাদ্দকে মঞ্জুরি দেয়, এর অর্থ তারা রানটাইম চলাকালীন মেমরি বরাদ্দ দেয় both

তাদের প্রোটোটাইপগুলি নিম্নরূপ:

void *malloc( size_t n);
void *calloc( size_t n, size_t t)

দুজনের মধ্যে প্রধানত দুটি পার্থক্য রয়েছে:

  • আচরণ: malloc()এটিকে আরম্ভ না করে একটি মেমরি ব্লক বরাদ্দ করে এবং এই ব্লক থেকে সামগ্রীগুলি পড়ার ফলে আবর্জনার মান হবে values calloc()অন্যদিকে, একটি মেমরি ব্লক বরাদ্দ করে এবং এটি শূন্যগুলিতে আরম্ভ করে এবং স্পষ্টতই এই ব্লকের বিষয়বস্তু পড়ার ফলে শূন্য হয়।

  • সিনট্যাক্স: malloc()1 টি আর্গুমেন্ট (বরাদ্দ করার আকার) calloc()নেয় এবং দুটি আর্গুমেন্ট নেয় (প্রতিটি ব্লকের বরাদ্দকৃত ব্লকের সংখ্যা এবং আকার)।

উভয় থেকে রিটার্ন মান সফল হলে মেমরির বরাদ্দ ব্লকের একটি পয়েন্টার। অন্যথায়, মেমরি বরাদ্দ ব্যর্থতা নির্দেশ করে NULL ফেরত দেওয়া হবে।

উদাহরণ:

int *arr;

// allocate memory for 10 integers with garbage values
arr = (int *)malloc(10 * sizeof(int)); 

// allocate memory for 10 integers and sets all of them to 0
arr = (int *)calloc(10, sizeof(int));

একই কার্যকারিতা calloc()যা ব্যবহার করে অর্জন করা যায় malloc()এবং memset():

// allocate memory for 10 integers with garbage values   
arr= (int *)malloc(10 * sizeof(int));
// set all of them to 0
memset(arr, 0, 10 * sizeof(int)); 

নোটটি malloc()অগ্রাধিকার হিসাবে calloc()এটি দ্রুত হওয়ার কারণে ব্যবহৃত হয় । যদি শূন্য-আরম্ভের মানগুলি চাওয়া হয় তবে calloc()পরিবর্তে ব্যবহার করুন।


5

একটি পার্থক্য এখনও উল্লেখ করা হয়নি: আকার সীমা

void *malloc(size_t size)কেবলমাত্র অবধি বরাদ্দ করতে পারে SIZE_MAX

void *calloc(size_t nmemb, size_t size);প্রায় বরাদ্দ করতে পারেন SIZE_MAX*SIZE_MAX

লিনিয়ার অ্যাড্রেসিং সহ অনেক প্ল্যাটফর্মগুলিতে এই ক্ষমতাটি প্রায়শই ব্যবহৃত হয় না। এই ধরনের ব্যবস্থা সীমিত calloc()সঙ্গে nmemb * size <= SIZE_MAX

কল করা এক ধরণের 512 বাইট বিবেচনা করুন disk_sectorএবং কোড প্রচুর সেক্টর ব্যবহার করতে চায় । এখানে কোড কেবলমাত্র SIZE_MAX/sizeof disk_sectorসেক্টর পর্যন্ত ব্যবহার করতে পারে ।

size_t count = SIZE_MAX/sizeof disk_sector;
disk_sector *p = malloc(count * sizeof *p);

নিম্নলিখিত আরও বিবেচনা করুন যা আরও বৃহত্তর বরাদ্দের অনুমতি দেয়।

size_t count = something_in_the_range(SIZE_MAX/sizeof disk_sector + 1, SIZE_MAX)
disk_sector *p = calloc(count, sizeof *p);

এখন যদি কোনও সিস্টেম এত বড় বরাদ্দ সরবরাহ করতে পারে তবে তা অন্য বিষয়। বেশিরভাগ আজ না। তবুও এটি বহু বছর ধরে ঘটেছিল যখন SIZE_MAX65৫৫৩৫ ছিল। মুরের আইন বিবেচনা করে সন্দেহ হয় যে এটি প্রায় ২০৩০ সালের মধ্যে কিছু নির্দিষ্ট মেমোরি মডেল SIZE_MAX == 4294967295এবং 100 গিগাবাইটের মেমরি পুল সহ ঘটবে।


2
সাধারণত সাইজ_টি কোনও প্রোগ্রাম হ্যান্ডেল করতে পারে এমন বৃহত্তম ধরণের আকারের আকার ধারণ করতে সক্ষম হবে। এমন একটি আকারে যেখানে সাইজ_টি 32 বিট হয় 4294967295 বাইটের চেয়ে বড় বরাদ্দ পরিচালনা করতে সক্ষম হয় না এবং এমন একটি সিস্টেম যা প্রায় size_t32 বিটের চেয়ে বড় আকারের বরাদ্দগুলি পরিচালনা করতে সক্ষম হবে । একমাত্র প্রশ্ন হ'ল এমন callocমানগুলির সাথে ব্যবহার করা যাঁর পণ্যটি অতিক্রম SIZE_MAXকরে তার চেয়ে কম বরাদ্দে কোনও পয়েন্টার ফিরিয়ে দেওয়ার পরিবর্তে শূন্যের জন্য নির্ভর করা যেতে পারে।
সুপারক্যাট

আপনার সম্পর্কে সম্মত সাধারণীকরণ , এখনো সি বৈশিষ্ট জন্য করতে পারবেন calloc()মাত্রাধিক বরাদ্দ SIZE_MAX। এটি 16-বিটের সাথে অতীতে ঘটেছিল এবং size_tস্মৃতিটি স্বল্পতর হওয়ার সাথে সাথে আমি সাধারণভাবে দেখা না গেলেও এটি এগিয়ে যাওয়ার কোনও কারণ দেখছি না ।
chux - মনিকা

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

তদ্ব্যতীত, অতীতে যেখানে সিস্টেমগুলি থাকতে পারে যার উপলভ্য ঠিকানাটি সর্বাধিক উপস্থাপনযোগ্য পূর্ণসংখ্যাকে ছাড়িয়ে গেছে, আমি আবার কখনও এটির কোন বাস্তব সম্ভাবনা দেখতে পাচ্ছি না, কারণ এর জন্য বিলিয়ন গিগাবাইটের স্টোরেজ ক্ষমতা প্রয়োজন capacity এমনকি যদি মুরের আইন ধরে রাখা অব্যাহত থাকে, যেখানে 32 বিট পর্যাপ্ত হতে পারে যেখানে b৪ বিট পর্যাপ্ত হয়ে যায় সেখানে পৌঁছাতে দ্বিগুণ সময় লাগবে যেখানে ১ 16 বিট পর্যায়ে ছিল যেখানে ৩২ টি বিট ছিল না 'টি।
ক্যাট

1
4G এর বেশি পরিমাণে একক বরাদ্দকে সামঞ্জস্য করতে পারে এমন একটি বাস্তবায়ন কেন সংজ্ঞায়িত size_tহবে না uint64_t?
সুপারক্যাট

2

ব্লকের সংখ্যা:
malloc () অনুরোধ করা মেমরির একক ব্লক বরাদ্দ করে,
কলোক () অনুরোধ করা মেমরির একাধিক ব্লক বরাদ্দ করে

প্রারম্ভিকরণ:
malloc () - বরাদ্দ মেমরি পরিষ্কার এবং আরম্ভ করে না।
কলোক () - বরাদ্দ করা স্মৃতি শূন্য দ্বারা সূচনা করে।

গতি:
malloc () দ্রুত।
কলোক () ম্যালোক () এর চেয়ে ধীর।

আর্গুমেন্টস এবং সিনট্যাক্স:
malloc () 1 টি আর্গুমেন্ট নেয়:

  1. বাইট

    • বাইট সংখ্যা বরাদ্দ করা হবে

কলোক () 2 টি আর্গুমেন্ট গ্রহণ করে:

  1. লম্বা

    • বরাদ্দ করার জন্য মেমরির ব্লকের সংখ্যা
  2. বাইট
    • মেমরির প্রতিটি ব্লকে বাইটের সংখ্যা বরাদ্দ করতে হবে
void *malloc(size_t bytes);         
void *calloc(size_t length, size_t bytes);      

মেমরির আদায় বরাদ্দ:
ম্যালোক ফাংশন উপলব্ধ হিপ থেকে পছন্দসই 'আকার' এর মেমরি বরাদ্দ করে
কলোক ফাংশন মেমরিকে নির্ধারণ করে যা 'সংখ্যা * আকার' এর সমান আকারের।

নামের অর্থ:
নাম ম্যালোক অর্থ "মেমরি বরাদ্দ"।
কলোক নামের অর্থ "সংগত বরাদ্দ"।

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