malloc এবং সুযোগ

আমি c তে malloc এর চারপাশে আমার মাথা মোড়ানো সংগ্রাম করছি - বিশেষ করে যখন এটি বিনামূল্যে() 'd হতে হবে। আমি gcc যেমন অদ্ভুত ত্রুটি হচ্ছে:

... ফ্রি (): অবৈধ পরবর্তী আকার (দ্রুত): ...

যখন আমি একটি গৃহস্থালি পয়েন্টার মুক্ত করার চেষ্টা করুন। উদাহরণস্বরূপ, একটি ইনপুট ফাইল থেকে পড়ার সময়, নিম্নলিখিত কাজ করার সময় এটি নির্দিষ্ট লাইনগুলিতে ক্র্যাশ হবে:

FILE *f = fopen(file,"r");
char x[256];
while(1) {
    if(fgets(x,sizeof x,f)==NULL) break;
    char *tmp = some_function_return_char_pointer(x); //OR malloc(nbytes);
   //do some stuff
    free(tmp);//this is where I get the error, but only sometimes
}

আমি সুস্পষ্ট জিনিসগুলির জন্য চেক করেছি, যেমন এক্স হচ্ছে নুল, কিন্তু এটি নেই; এটা শুধু এলোমেলো রেখা ক্র্যাশ।

কিন্তু আমার আসল প্রশ্ন হল - কখন আমাকে বিনামূল্যে() ব্যবহার করতে হবে? অথবা, সম্ভবত আরো সঠিকভাবে, কখন আমি বিনামূল্যে ব্যবহার করা উচিত নয়? যদি malloc একটি ফাংশন হয়, এবং আমি malloc() ব্যবহার করা var var ফিরে? একটি জন্য বা যখন লুপ সম্পর্কে কি? Struct এর একটি অ্যারের জন্য malloc-ing একটি স্ট্রিং/গৃহস্থালি পয়েন্টার জন্য একই নিয়ম আছে?

আমি প্রোগ্রাম ক্র্যাশ উপর gcc পেয়েছি ত্রুটি থেকে জড়ো যে আমি malloc এবং বিনামূল্যে বুঝতে না। আমি গুগল এর সাথে আমার মানের সময় কাটিয়েছি এবং এখনও আমি ইট দেয়াল মারছি। আপনি পেয়েছেন কোন ভাল সম্পদ আছে? আমি যা দেখি তা বলে যে যখনই আমি ম্যালোক ব্যবহার করি তখন আমাকে বিনামূল্যে ব্যবহার করতে হবে। কিন্তু তারপর আমি যে চেষ্টা এবং আমার প্রোগ্রাম ক্র্যাশ। সুতরাং এটি একটি পরিবর্তনশীল এর সুযোগ উপর ভিত্তি করে ভিন্ন হতে পারে? যখন একটি পরিবর্তনশীল ঘোষণা করা হয় তখন একটি লুপের শেষে সিটি মেমরি মুক্ত করে? একটি ফাংশন শেষে?

তাই:

for(i=0;i<100;i++) char *x=malloc(n);//no need to use free(x)?

কিন্তু:

char *x;
for(i=0;i<100;i++) {
    x=malloc(n);
    free(x); //must do this, since scope of x greater than loop?
}

এটা কি সঠিক?

আশা করি আমি বুঝছি ...

1
আপনি malloc (), আপনি বিনামূল্যে এটি (একবার) যখন আপনি এটি ব্যবহার করার প্রয়োজন নেই।
যোগ লেখক Mitch Wheat, উৎস

7 উত্তর

malloc() is C's dynamic allocator. You have to understand the difference between automatic (scoped) and dynamic (manual) variables.

Automatic variables live for the duration of their scope. They're the ones you declare without any decoration: int x;

Most variables in a C program should be automatic, since they are local to some piece of code (e.g. a function, or a loop), and they communicate via function calls and return values.

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

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

সংক্ষেপে, পরিবর্তনশীল বরাদ্দ মৌলিকভাবে এবং প্রাথমিকভাবে সুযোগ এর একটি প্রশ্ন। যদি সম্ভব হয় সবকিছু স্বয়ংক্রিয় রাখা এবং আপনি কিছু করতে হবে না। প্রয়োজন হলে, গতিশীল বরাদ্দ ব্যবহার করুন এবং যথাযথ যখনই ম্যানুয়ালি deallocate যত্ন নিতে।

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

5
যোগ
যখনই সম্ভব গতিশীল বরাদ্দ এড়াতে উপদেশের জন্য +1।
যোগ লেখক R.., উৎস
@ ওলিছারলেসওয়ার্থঃ আহ, হ্যা, আরেকটা ভালো পয়েন্ট! সম্পাদনা করা হয়েছে।
যোগ লেখক Kerrek SB, উৎস
যখন এটি malloc এর উপযুক্ত (না) খেয়েছে তখন অসাধারণ ব্যাখ্যা
যোগ লেখক g33kz0r, উৎস
আপনি স্পষ্টভাবে ব্যাখ্যা করেছেন উপায়। পিএইচপি থেকে আসছে যেখানে $ x = "কিছু স্ট্রিং"; , আমি malloc ব্যবহারের জন্য প্রতিস্থাপন করার চেষ্টা করছি; এটা গতিশীল, এবং স্বয়ংক্রিয় নয়, বরাদ্দ হিসাবে বর্ণনা করার জন্য অনেক বেশি ইন্দ্রিয় তোলে
যোগ লেখক cegfault, উৎস
যখন আপনি একটি বৃহত অ্যারে (উদাঃ একটি মিলিয়ন উপাদানের) যা স্ট্যাক ভাঙ্গতে হবে, তখন ডাইনিং বরাদ্দকরণের ক্ষেত্রে গতিশীল বরাদ্দের একটি উদাহরণ নেই।
যোগ লেখক Oliver Charlesworth, উৎস

সাধারণভাবে, malloc এ থাকা প্রতিটি কলটিতে এক সংশ্লিষ্ট কলটি বিনামূল্যে থাকতে হবে। * এর সাথে কিছুই করার নেই সুযোগ (অর্থাত ফাংশন বা loops সঙ্গে কি কিছুই)।


* এই নিয়মটির ব্যতিক্রমগুলি strdup এর মতো ফাংশন ব্যবহার করে, তবে নীতিটি একই।
3
যোগ
@xixonia: একটি ক্র্যাশ হল সেরা-কেস দৃশ্যকল্প এবং আপনি কী আশা করেন তা নয়। সবচেয়ে খারাপ কেস একটি আক্রমণকারী রুট প্রদান করা হয়।
যোগ লেখক R.., উৎস
@xixonia: সম্পন্ন!
যোগ লেখক Oliver Charlesworth, উৎস
@ আর .., এই সব আমাকে শুধু সি ফিরে পেতে চান :)
যোগ লেখক cwharris, উৎস
এখানে উল্লেখ্য গুরুত্বপূর্ণ, যে ফ্রি (...) কে কল করলে ক্র্যাশ হতে পারে।
যোগ লেখক cwharris, উৎস

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

2
যোগ

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

1
যোগ
কঠোরভাবে বলতে গেলে, সি শব্দটি "স্টোরেজ সময়কাল" নয়, "জীবনকাল"। :-)
যোগ লেখক R.., উৎস
@ ওলিভার চার্লসওয়ার্থ, ওহ স্ন্যাপ যুদ্ধের শব্দ :: পপস পপকর্ন ::
যোগ লেখক user1717828, উৎস
আপনি "জীবনকাল" মানে, "সুযোগ" না। সুযোগ সনাক্তকারী, প্রযোজ্য নয় প্রযোজ্য।
যোগ লেখক Oliver Charlesworth, উৎস
@ র।: না, আমি সত্যিই "জীবনকাল" মানে; 6.2.4 ধারা 2 দেখুন।
যোগ লেখক Oliver Charlesworth, উৎস

যখন আপনি আর অ্যাক্সেস করবেন না তখন আপনাকে স্মৃতি মুক্ত করতে হবে। আপনি এটি অ্যাক্সেস করা হবে যদি আপনি মেমরি মুক্ত করা উচিত নয়। এই আপনি ব্যথা অনেক দিতে হবে।

0
যোগ

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

int* allocate_an_integer_array(int n)
{
    int* p = (int*) (malloc(sizeof(int)*n));
    return p;
}

এই ফাংশনগুলি কেবল মেপে সমান এন পূর্ণসংখ্যা থেকে মেমরি বরাদ্দ করে এবং প্রথম অবস্থানে একটি পয়েন্টার প্রদান করে। আপনি চান হিসাবে পয়েন্টার কলিং ফাংশন ব্যবহার করা যেতে পারে। পয়েন্টার যতক্ষণ আপনার সাথে থাকে যতক্ষণ SCOPE ব্যাপার না ..

বিনামূল্যে (পি) মেমরি মেমরি ফিরে।

আপনাকে মনে রাখতে হবে যে একমাত্র জিনিস এটি মুক্ত করা এবং এটির ঠিকানাটির মূল্য হারাতে হলে এটি একটি মেমরি লিক বাউড করবে। এটি তাই কারণ OS এর মতে, আপনি এখনও এটির মাধ্যেমে ব্যবহার করছেন না কারণ আপনি এটি মুক্ত করেছেন এবং একটি মেমরি লিক ঘটবে।

এছাড়াও মুক্ত করার পরে পয়েন্টারের মানটি নিলতে সেট করুন যাতে আপনি এটি পুনরায় ব্যবহার না করেন কারণ একই মেমরিটি অন্য কোনও উদ্দেশ্যে অন্য কোনও সময়ে আবার বরাদ্দ করা যেতে পারে।

তাই, আপনাকে যা করতে হবে তা সাবধান হতে হবে ...

আশা করি এটা সাহায্য করবে!

0
যোগ

আপনি যদি মেমরি লিক না চান তবে আপনাকে মেমোক থেকে মেমরি মুক্ত করতে হবে।

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

কখনও কখনও আমরা মেমরি লিক যত্ন না। স্মৃতিচারণ সমগ্র জীবনকালের সময় প্রয়োজন যে কিছু থাকে, আপনি এটি মুক্ত না চয়ন করতে পারেন। উদাহরণ: পরিবেশ পরিবর্তনশীল জন্য একটি স্ট্রিং।

PS: Valgrind একটি মেমরি বাগ সনাক্ত করতে সহায়তা করার জন্য একটি সরঞ্জাম। মেমরি লিক জন্য বিশেষ করে দরকারী।

0
যোগ
যদি আমার সহকর্মীরা লাইব্রেরি কোডে মেমরি লিক রেখে যায়, আমি একটি টিকিট বাড়াতে এবং এটি ঠিক করার জন্য পেতে পারি ...
যোগ লেখক Oliver Charlesworth, উৎস
না আমরা না, আমরা কেবল আমাদের মেমরি সঠিকভাবে পরিষ্কার করতে পারেন।
যোগ লেখক Oliver Charlesworth, উৎস
এটির জীবনকাল সম্পূর্ণরূপে নির্বাহের কারণেই কিছু মুক্ত করা খুব দরিদ্র অভ্যাস। একটি শুরু করার জন্য, এটি ত্রুটি সঙ্গে আপনার Valgrind আউটপুট swamps।
যোগ লেখক Oliver Charlesworth, উৎস
আমি রাজী. কিন্তু আমরা যে সঙ্গে বসবাস করতে হবে।
যোগ লেখক Cha Cha, উৎস
কোডগুলি লেখার জন্য আপনি যদি শুধুমাত্র একমাত্র হন তবে কোনও লাইব্রেরি ব্যবহার করবেন না। বাস্তবতা আপনার সহকর্মীদের এই মত কোড; এবং আপনি নির্ভর করে লাইব্রেরি মেমরি মুক্ত নাও হতে পারে।
যোগ লেখক Cha Cha, উৎস
ঠিক আছে, আপনি একটি বিন্দু আছে। আমি putenv (strdup (...) এর জন্য মেমরি মুক্ত করতে আমার সহকর্মীদের সন্তুষ্ট করতে যাচ্ছি। আমি তাদের কাজ পেতে চেষ্টা করবে। ধন্যবাদ.
যোগ লেখক Cha Cha, উৎস