উত্তর:
স্পেসিফিকেশন অনুযায়ী, malloc (0) "নাল পয়েন্টার বা একটি অনন্য পয়েন্টার যা সফলভাবে ফ্রি ()" এ পাস হতে পারে "ফিরে আসবে।"
এটি মূলত আপনাকে কিছুই বরাদ্দ করতে দেয় তবে তবুও "শিল্পী" ভেরিয়েবলটি বিনা উদ্বেগের () মুক্ত করতে একটি কলটিতে পাস করে। ব্যবহারিক উদ্দেশ্যে, এটি করার মতো প্রায় একই রকম:
artist = NULL;
সি স্ট্যান্ডার্ড (C17 7.22.3 / 1) বলেছেন:
যদি অনুরোধ করা জায়গার আকার শূন্য হয়, আচরণটি বাস্তবায়িত সংজ্ঞায়িত হয়: হয় নাল পয়েন্টারটি ফেরত দেওয়া হয়, বা আচরণটি এমন হয় যেন আকারটি কিছু ননজারো মান হয়, ব্যতীত প্রত্যাবর্তিত পয়েন্টারটি কোনও বস্তু অ্যাক্সেস করতে ব্যবহৃত হবে না।
সুতরাং, malloc(0)
ফিরে আসতে পারে NULL
বা একটি বৈধ পয়েন্টার যা অবহিত নাও হতে পারে । উভয় ক্ষেত্রেই, কল করার পক্ষে এটি পুরোপুরি বৈধfree()
।
উদাহরণস্বরূপ malloc(0)
যখন malloc(n)
কোনও লুপে ডাকা হয় তখন এবং আমি সত্যিকার অর্থে খুব বেশি ব্যবহার করি বলে মনে করি নাn
এটি শূন্য হতে পারে ।
লিঙ্কটিতে কোডটি দেখলে, আমি বিশ্বাস করি যে লেখকের দুটি ভুল ধারণা ছিল:
malloc(0)
সর্বদা একটি বৈধ পয়েন্টার দেয় , এবংfree(0)
খারাপ.সুতরাং, তিনি নিশ্চিত করেছেন যে artist
এবং অন্যান্য ভেরিয়েবলগুলির মধ্যে সর্বদা কিছু "বৈধ" মান থাকে। মন্তব্য যতটা বলেছেন: // these must always point at malloc'd data
।
malloc(0)
কোনও বৈধ পয়েন্টার ফিরিয়ে দেওয়া হয়, তবে malloc()
প্রত্যাবর্তনের NULL
অর্থ সর্বদা "ব্যর্থতা" এবং 0
এটি কোনও বিশেষ ক্ষেত্রে নয়, যা আরও সামঞ্জস্যপূর্ণ।
malloc
স্মৃতিশক্তি অর্জনে ব্যর্থতার পরিস্থিতি বাস্তবায়ন-সংজ্ঞায়িত, তাই একটি বাস্তবায়ন কেবলমাত্র আকার -0 বরাদ্দকে সর্বদা অসম্পৃক্ত (( ENOMEM
)) হিসাবে সংজ্ঞায়িত করতে পারে এবং এখন malloc(0)
0 (সহ errno==ENOMEM
) ফিরিয়ে দেওয়া সামঞ্জস্যপূর্ণ। :-)
realloc
একটি পয়েন্টার দ্বারা ফিরে আসতে পারেন malloc(0)
? পারবেন তো realloc((char*)NULL)
?
malloc (0) আচরণ হ'ল বাস্তবায়ন নির্দিষ্ট। লাইব্রেরিটি NULL ফিরিয়ে দিতে পারে বা নিয়মিত ম্যালোক আচরণ করতে পারে, কোনও স্মৃতি বরাদ্দ না দিয়ে। এটি যাই করুক না কেন এটি অবশ্যই কোথাও নথিভুক্ত হতে হবে।
সাধারণত, এটি এমন পয়েন্টারটি দেয় যা বৈধ এবং অনন্য তবে এটি ডিফারেন্স করা উচিত নয়। এছাড়াও মনে রাখবেন যে এটি মেমরি গ্রাস করতে পারে যদিও এটি আসলে কিছু বরাদ্দ দেয় না।
একটি নন নল ম্যালোক (0) পয়েন্টারটি পুনরায় চালু করা সম্ভব।
ম্যালোক (0) ভারব্যাটিম থাকা যদিও খুব বেশি ব্যবহার হয় না। এটি বেশিরভাগ ক্ষেত্রে ব্যবহৃত হয় যখন একটি গতিশীল বরাদ্দ শূন্য বাইট হয় এবং আপনি এটি যাচাই করার যত্ন নেন না।
malloc()
অবশ্যই "হাউসকিপিং তথ্য" কোথাও রাখতে হবে (উদাহরণস্বরূপ বরাদ্দকৃত ব্লকের এই আকার এবং অন্যান্য সহায়ক ডেটা)। সুতরাং, যদি malloc(0)
না ফিরে আসে NULL
, এটি তথ্য সংরক্ষণের জন্য মেমরি ব্যবহার করবে এবং যদি তা না হয় তবে free()
মেমরি ফাঁস হয়ে যাবে।
malloc()
ফিরে আসবে না, বা ফিরে যাবে না NULL
।
malloc(0)
। যাইহোক, স্ট্যান্ডার্ড সি লাইব্রেরির একেবারে একই বাস্তবায়নে realloc(ptr, 0)
NUL কে মুক্তি দেয় ptr
এবং ফেরত দেয়।
এই পৃষ্ঠায় অন্য কোথাও একটি উত্তর রয়েছে যা শুরু হয় "malloc (0) একটি বৈধ মেমরি ঠিকানা ফিরে আসবে এবং যার পরিসীমা পয়েন্টারের ধরণের উপর নির্ভর করবে যা মেমরি বরাদ্দ করা হচ্ছে"। এই বিবৃতিটি ভুল (আমার সরাসরি উত্তরের বিষয়ে মন্তব্য করার মতো খ্যাতি নেই, সুতরাং এই মন্তব্যটি এখানে সরাসরি রাখতে পারি না)।
ম্যালোক (0) করলে স্বয়ংক্রিয়ভাবে সঠিক আকারের মেমরি বরাদ্দ হবে না । ম্যালোক ফাংশনটি আপনি কী ফলাফলটি কাস্ট করছেন তাতে অজানা। ম্যালোক ফাংশনটি তার যুক্তি হিসাবে আপনি যে আকার সংখ্যায় দেন তার উপর সম্পূর্ণ নির্ভর করে। কোন int রাখার জন্য পর্যাপ্ত স্টোরেজ পাওয়ার জন্য আপনাকে ম্যালোক (মাপের (আকার)) করতে হবে, উদাহরণস্বরূপ, 0 নয়।
malloc(0)
কোডটি বাস্তবায়নের জন্য নির্দিষ্ট আচরণের উপর নির্ভর না করে আমার কাছে কোনও অর্থবোধ করে না। কোডটি যদি পোর্টেবলের উদ্দেশ্যে বোঝানো হয়, তবে এটির জন্য অ্যাকাউন্টটির জবাবদিহি করতে হবে যে কোনও নূলে ফিরে আসা malloc(0)
কোনও ব্যর্থতা নয়। সুতরাং কেন artist
যে কোনও উপায়ে কেবল NULL বরাদ্দ করবেন না, কারণ এটি একটি বৈধ সফল ফলাফল, এবং কম কোড, এবং আপনার রক্ষণাবেক্ষণ প্রোগ্রামারগুলিকে এটি নির্ধারণে সময় দেবে না?
malloc(SOME_CONSTANT_THAT_MIGHT_BE_ZERO)
অথবা malloc(some_variable_which_might_be_zero)
সম্ভবত তাদের ব্যবহারগুলি থাকতে পারে, যদিও আবার আপনাকে NUL রিটার্নটিকে ব্যর্থতা হিসাবে বিবেচনা না করার জন্য অতিরিক্ত যত্ন নিতে হবে যদি মান 0 হয় তবে 0 টি আকার ঠিক আছে বলে মনে করা হচ্ছে।
এখানে প্রায় অর্ধেক সত্য উত্তর রয়েছে, সুতরাং এখানে কঠোর তথ্য রয়েছে। ম্যান পেজ malloc()
বলেছেন:
যদি আকার 0 হয়, তবে ম্যালোক () NULL হয়, বা একটি অনন্য পয়েন্টার মান যা পরে সফলভাবে ফ্রি () এ পাস করতে পারে returns
এর অর্থ, এর কোনও গ্যারান্টি নেই যে এর ফলাফলটি malloc(0)
অনন্য বা না নূরের নয়। একমাত্র গ্যারান্টিটি free()
আবার সংজ্ঞা দ্বারা প্রদত্ত হয়েছে, ম্যান পৃষ্ঠাটি যা বলেছে:
যদি পিটিআরটি নুল হয় তবে কোনও অপারেশন করা হয় না।
সুতরাং, যাই হোক না কেন malloc(0)
, এটি নিরাপদে দেওয়া যেতে পারে free()
। কিন্তু তাই একটি NULL
পয়েন্টার করতে পারেন ।
ফলস্বরূপ, লেখার artist = malloc(0);
চেয়ে কোনওভাবেই লেখার চেয়ে ভাল হয় না artist = NULL;
malloc(0)
0x1 বলে, ফিরে আসতে পারে এবং 0x1 এর মতো 0x1 এর free()
একটি বিশেষ-কেস চেক থাকতে পারে।
NULL
, বা একটি অনন্য পয়েন্টার" অবশ্যই নির্দিষ্ট করে না । । পরিবর্তে 'হয় একটি নাল পয়েন্টার বা বরাদ্দ স্থান "একটি পয়েন্টার আছে নেই অনন্য প্রয়োজন OTOH, একটি অ-অনন্য বিশেষ মান ফিরে কোড ব্যাহত করতে পারে যে অনন্য মান উপর গন্য জন্য তাই সম্ভবত একটি কোণায় কেস
man
পাশাপাশি * নিক্সে ব্যবহৃত প্রয়োগ-সংজ্ঞায়িত ফর্মটি নথিভুক্ত করতে পারে। এক্ষেত্রে এটি হয় না, তবে এটি এখনও সাধারণ সি এর পক্ষে কোনও প্রচলিত উত্স নয়
কেন আপনি এটি করবেন না ...
যেহেতু malloc এর রিটার্ন মান বাস্তবায়ন নির্ভর, আপনি একটি NULL পয়েন্টার বা অন্য কোনও ঠিকানা ফিরে পেতে পারেন। যদি ত্রুটি পরিচালনা করার কোডটি আকার এবং প্রত্যাশিত মান উভয়ই পরীক্ষা না করে তবে স্থায়িত্বের সমস্যাগুলি (ক্র্যাশগুলি) বা আরও খারাপ সুরক্ষার সমস্যার কারণ হয়ে থাকে তবে হিপ-বাফার ওভারফ্লোগুলি তৈরির অবসান ঘটতে পারে।
এই উদাহরণটি বিবেচনা করুন, যেখানে ফেরত ঠিকানার মাধ্যমে মেমরির আরও অ্যাক্সেস করা হ'ল যদি আকারটি শূন্য হয় এবং বাস্তবায়ন একটি নন-মান মূল্য ফিরে দেয় corrupt
size_t size;
/* Initialize size, possibly by user-controlled input */
int *list = (int *)malloc(size);
if (list == NULL) {
/* Handle allocation error */
}
else {
/* Continue processing list */
}
CERT কোডিং স্ট্যান্ডার্ডগুলি থেকে এই সুরক্ষিত কোডিং পৃষ্ঠাটি দেখুন যেখানে আমি আরও পড়ার জন্য উপরের উদাহরণটি নিয়েছি।
স্বীকারোক্তিজনকভাবে, আমি এটি আগে কখনও দেখিনি, আমি এই সিনট্যাক্সটি প্রথম দেখলাম, কেউ বলতে পারে, ফাংশন ওভারকিলের একটি সর্বোত্তম ক্ষেত্রে। রিডের উত্তরের সাথে মিল রেখে আমি এটি উল্লেখ করতে চাই যে একই রকম একটি জিনিস রয়েছে, এটি একটি ওভারলোডেড ফাংশনের মতো প্রদর্শিত realloc
:
realloc(foo, size);
,। যখন আপনি একটি নন-নুল পয়েন্টার এবং শূন্যের আকার থেকে রিললকে পাস করেন, রিলোক এমন আচরণ করে যেন আপনি মুক্ত কল করেছেন (…)realloc(foo, size);
। আপনি যখন কোনও নুল পয়েন্টারে পাস করেন এবং আকারটি শূন্য নয়, তখন রিলোক এমন আচরণ করে যে আপনি মলোককে ডাকলেন (…)আশা করি এই সাহায্য করবে, শুভেচ্ছা, টম।
malloc (0) NULL বা একটি বৈধ পয়েন্টার ফিরিয়ে দেবে যা সঠিকভাবে ফ্রিতে পাঠানো যেতে পারে। এবং যদিও এটি মনে হয় এমন স্মৃতি যেমন মনে হয় এটি অকেজো বা এটি লেখা বা পড়া যায় না, এটি সর্বদা সত্য নয়। :)
int *i = malloc(0);
*i = 100;
printf("%d", *i);
আমরা এখানে বিভাজন ত্রুটি আশা করি, কিন্তু আশ্চর্যের বিষয় এই 100 টি প্রিন্ট করে! এটি কারণ যখন আমরা প্রথমবার ম্যালোককে কল করি তখন ম্যালোক প্রকৃতপক্ষে একটি বিশাল পরিমাণ স্মৃতি চেয়ে থাকে। এর পরে ম্যালোকের প্রতিটি কল, সেই বড় অংশের মেমরি ব্যবহার করে। সেই বিশাল অংশ শেষ হওয়ার পরেই নতুন মেমরির জন্য বলা হয়।
মেলোক (0) এর ব্যবহার: আপনি যদি এমন পরিস্থিতিতে থাকেন যেখানে আপনি পরবর্তী ম্যালোক কলগুলি দ্রুততর করতে চান, ম্যালোককে কল (0) আপনার জন্য করা উচিত (প্রান্তের কেসগুলি ব্যতীত)।
*i
আপনার ক্ষেত্রে ক্র্যাশ নাও হতে পারে তবে তবুও এটি অপরিজ্ঞাত আচরণ। অনুনাসিক অসুরদের জন্য সতর্কতা অবলম্বন করুন!
malloc(0)
উল্লেখ নেই। সেই বাস্তবায়নগুলিতে যেখানে এটি একটি অ-নুল মান প্রদান করে, বিশেষত একটি ডিইবিইউজি বিল্ডে, এটি সম্ভবত আপনার চেয়ে বেশি বরাদ্দ করে এবং আপনাকে কেবল অভ্যন্তরীণ শিরোনাম পেরিয়ে যাওয়ার জন্য নির্দেশক দেয়। এটি বরাদ্দের একটি সিরিজের আগে এবং পরে আপনি যদি এটি পেয়ে থাকেন তবে এটি আপনাকে প্রকৃত মেমরির ব্যবহারের জন্য অনুভূতি পেতে দেয় । যেমন: void* before = malloc(0); ... void* after = malloc(0); long long total = after - before;
বা এই জাতীয় কিছু।
malloc(0)
। আপনি দয়া করে বলতে পারেন কোন অধ্যায়টি আপনি খুব উল্লেখ করছেন? একটি সঠিক উদ্ধৃতি প্রদান করা খুব ভাল হবে।
উইন্ডোজে:
void *p = malloc(0);
স্থানীয় স্তূপে একটি শূন্য দৈর্ঘ্যের বাফার বরাদ্দ করবে। ফিরে আসা পয়েন্টারটি একটি বৈধ হিপ পয়েন্টার।malloc
শেষ পর্যন্ত HeapAlloc
ডিফল্ট সি রানটাইম হিপ ব্যবহার করে কলগুলি আসে যার পরে কল হয় RtlAllocateHeap
etc.free(p);
HeapFree
স্তূপে 0-দৈর্ঘ্যের বাফার মুক্ত করতে ব্যবহার করে। এটি মুক্ত না করলে মেমোরি ফাঁস হয়।এটি আসলে বেশ কার্যকর, এবং (স্পষ্টতই আইএমএইচও), কোনও এনএলএল পয়েন্টার ফেরতের অনুমতিপ্রাপ্ত আচরণটি ভেঙে গেছে। একটি গতিশীল পয়েন্টার কেবল এটি যেটির দিকে নির্দেশ করে তা নয়, তবে এটির ঠিকানাটিও অনন্য unique NULL ফিরিয়ে দেওয়া সেই দ্বিতীয় সম্পত্তিটি সরিয়ে দেয়। আমি এম্বেড করা সমস্ত ম্যালোকস প্রোগ্রাম (বেশিরভাগ ক্ষেত্রে বাস্তবে) এই আচরণ করে।
নিশ্চিত নয়, আমি খুঁজে পাওয়া কিছু এলোমেলো ম্যালোক সোর্স কোড অনুসারে 0 টির একটি ইনপুট NULL এর রিটার্ন মান হিসাবে ফলাফল করে। সুতরাং এটি শিল্পীর পয়েন্টারটিকে NULL এ সেট করার একটি উন্মাদ উপায়।
http://www.raspberryginger.com/jbailey/minix/html/lib_2ansi_2malloc_8c-source.html
ভালগ্রাইন্ড মেমরি চেক সরঞ্জামটি চালানোর পরে বিশ্লেষণটি এখানে।
==16740== Command: ./malloc0
==16740==
p1 = 0x5204040
==16740==
==16740== HEAP SUMMARY:
==16740== in use at exit: 0 bytes in 0 blocks
==16740== total heap usage: 2 allocs, 2 frees, 1,024 bytes allocated
==16740==
==16740== All heap blocks were freed -- no leaks are possible
এবং এখানে আমার নমুনা কোড:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
//int i;
char *p1;
p1 = (char *)malloc(0);
printf("p1 = %p\n", p1);
free(p1);
return 0;
}
ডিফল্টরূপে 1024 বাইট বরাদ্দ করা হয়। যদি আমি ম্যালোকের আকার বাড়িয়ে নিই তবে বরাদ্দ করা বাইটগুলি 1025 এবং আরও বৃদ্ধি পাবে।
মতে রিড Copsey উত্তর এবং malloc লোক পৃষ্ঠা, আমি পরীক্ষা কিছু উদাহরণ লিখেছিলেন। এবং আমি খুঁজে পেলাম malloc (0) সর্বদা এটির একটি অনন্য মান দেবে। আমার উদাহরণ দেখুন:
char *ptr;
if( (ptr = (char *) malloc(0)) == NULL )
puts("Got a null pointer");
else
puts("Got a valid pointer");
আউটপুটটি "একটি বৈধ পয়েন্টার পেয়েছি" হবে, যার অর্থ ptr
নাল নয়।
malloc(0)
একটি বৈধ মেমরি ঠিকানা প্রদান করবে এবং যার পরিসীমা পয়েন্টারের ধরণের উপর নির্ভর করবে যা মেমরি বরাদ্দ করা হচ্ছে। এছাড়াও আপনি মেমরির ক্ষেত্রে মানগুলি নির্ধারণ করতে পারেন তবে এটি ব্যবহৃত পয়েন্টারের ধরণের সাথে হওয়া উচিত। আপনি বরাদ্দ মেমরি বিনামূল্যে করতে পারেন। আমি এটি একটি উদাহরণ দিয়ে ব্যাখ্যা করব:
int *p=NULL;
p=(int *)malloc(0);
free(p);
উপরের কোডটি gcc
লিনাক্স মেশিনের একটি সংকলনে সূক্ষ্মভাবে কাজ করবে । আপনার যদি 32 বিট সংকলক থাকে তবে আপনি পূর্ণসংখ্যার ব্যাপ্তিতে মানগুলি সরবরাহ করতে পারেন, যেমন -2147483648 থেকে 2147483647 S একই অক্ষরগুলির ক্ষেত্রেও প্রযোজ্য। দয়া করে নোট করুন যে ঘোষিত পয়েন্টার ধরণের পরিবর্তন করা থাকলে malloc
টাইপকাস্ট, নির্বিশেষে মানগুলির পরিসীমা পরিবর্তিত হবে
unsigned char *p=NULL;
p =(char *)malloc(0);
free(p);
p
এটি একটি স্বাক্ষরবিহীন int হিসাবে ঘোষিত হওয়ার কারণে চরের 0 থেকে 255 পর্যন্ত মান নেবে।
malloc()
সম্পর্কে কিছুই জানেন না (যা আসলে পুরোপুরি সিতে অতিমাত্রায় রয়েছে )। এর রিটার্ন মানকে নির্ধারণ করা malloc(0)
অনির্ধারিত আচরণকে ডেকে আনে ।
এখানে একটি মিথ্যা ছাপ সংশোধন করতে:
artist = (char *) malloc(0);
কখনও ফিরে আসবে না NULL
; এটা যেমন হয় না artist = NULL;
। একটি সহজ প্রোগ্রাম লিখুন এবং তুলনা artist
সঙ্গে NULL
। if (artist == NULL)
মিথ্যা এবং if (artist)
সত্য।