মলোক বনাম নতুন - বিভিন্ন প্যাডিং


110

আমি আমাদের প্রকল্পের জন্য অন্য কারও সি ​​++ কোড পর্যালোচনা করছি যা উচ্চ-পারফরম্যান্স কম্পিউটিংয়ের জন্য এমপিআই ব্যবহার করে (10 ^ 5 - 10 ^ 6 কোর)। কোডটি বিভিন্ন আর্কিটেকচারে (সম্ভাব্য) বিভিন্ন মেশিনের মধ্যে যোগাযোগের অনুমতি দেওয়ার উদ্দেশ্যে তৈরি করা হয়েছে। তিনি একটি মন্তব্য লিখেছেন যা এর লাইনে কিছু বলেছে:

আমরা সাধারণত ব্যবহার করব newএবং delete, কিন্তু এখানে আমি ব্যবহার করছি mallocএবং free। এটি প্রয়োজনীয় কারণ কারণ কিছু সংকলকগণ যখন newব্যবহৃত হয় তখন ডেটা আলাদাভাবে প্যাড করে দেয় , ফলে বিভিন্ন প্ল্যাটফর্মের মধ্যে ডেটা স্থানান্তর করতে ত্রুটি দেখা দেয়। এটি সঙ্গে হয় না malloc

স্ট্যান্ডার্ড newবনাম mallocপ্রশ্নগুলি থেকে আমি জানি এমন কোনও কিছুর সাথে এটি খাপ খায় না ।

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

ম্যালোক ও প্লেসমেন্ট নতুন বনাম নতুন একটি মোটামুটি জনপ্রিয় প্রশ্ন তবে কেবল newযেখানে কনস্ট্রাক্টরগুলি ব্যবহার mallocকরেন না যেখানে এটি প্রাসঙ্গিক নয় সেগুলি ব্যবহারের বিষয়ে কথা বলে।

malloc কিভাবে প্রান্তিককরণ বুঝতে পারে? বলেছেন যে মেমরির গ্যারান্টিযুক্ত সঠিকভাবে যেকোন একটির সাথে একত্রিত হবে newবা mallocযা আমি আগে ভেবেছিলাম।

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

আমাকে সহায়তা করুন, স্ট্যাকওভারফ্লো, আপনি আমার একমাত্র আশা!


33
একা বিভিন্ন এসও থ্রেডের গবেষণার জন্য +1!
iammilind

7
+1 খুব দীর্ঘ একটি "আমি নিজেই আগে জিজ্ঞাসা করি-অন্যদের" গবেষণা কাজগুলির মধ্যে সহজেই আমি 'এসও'তে দেখেছি research আশা করি আমি আরও কয়েকবার এটি উত্সাহ দিতে পারতাম।
WhozCraig

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

1
বাহ আমি এই প্রশ্নটি এই জনপ্রিয় হওয়ার প্রত্যাশা করছিলাম না! @ লিন্ডাডান্সার, আমার মনে হয় না যে কোনও 8-বাইট সীমানা অনুমান করা হয়েছে। আকর্ষণীয় বিষয় যদিও।
hcarver

1
অন্যের জন্য একটি বরাদ্দ পদ্ধতি ব্যবহার করার একটি কারণ হ'ল "অন্য কেউ" যখন অবজেক্টটি প্রকাশ করে। যদি এই "অন্য কেউ" ফ্রি ব্যবহার করে অবজেক্টটি মুছতে থাকে, আপনাকে অবশ্যই ম্যালোক ব্যবহার করে বরাদ্দ দিতে হবে। (একজন প্যাড ইস্যু একটি লাল হেরিং হয়।)
Lindydancer

উত্তর:


25

আইআইআরসি একটি পিক পয়েন্ট আছে। mallocকোনও মানক প্রকারের জন্য সারিবদ্ধ ঠিকানা ফেরতের গ্যারান্টিযুক্ত। এন এর চেয়ে বড়::operator new(n) কোন স্ট্যান্ডার্ড টাইপের জন্য প্রান্তিকৃত ঠিকানাটি ফেরত পাওয়ার গ্যারান্টিযুক্ত এবং যদি কোনও অক্ষর প্রকার না হয় তবে কেবল ঠিক জন্য প্রান্তিকিত কোনও ঠিকানা ফেরত দেওয়া প্রয়োজন ।Tnew T[n]T

তবে এটি কেবলমাত্র তখনই প্রাসঙ্গিক, যখন আপনি পতাকা সংরক্ষণের জন্য পয়েন্টারের নীচে কয়েকটি বিট ব্যবহার করা বা অন্যথায় ঠিকানার প্রয়োজন অনুসারে ঠিক মতো প্রান্তিককরণের জন্য ঠিকানার উপর নির্ভর করা যেমন বাস্তবায়ন-নির্দিষ্ট কৌশলগুলি খেলেন।

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

এই মন্তব্যের লেখক স্ট্যাকের উপর বা গ্লোবালগুলিতে কী ভাবছেন, তার কোনও মতামত আছে কি না, তার মতে তারা "ম্যালোকের মতো প্যাডেড" বা "নতুনের মতো প্যাডেড" কিনা? ধারণাটি কোথা থেকে এসেছে তা ক্লু দিতে পারে।

হয়তো তিনি বিভ্রান্ত, কিন্তু হয়তো কোড তিনি কথা বলা হচ্ছে মধ্যে একটি সোজা পার্থক্য বেশী malloc(sizeof(Foo) * n)বনাম new Foo[n]। সম্ভবত এটি আরও মত:

malloc((sizeof(int) + sizeof(char)) * n);

বনাম

struct Foo { int a; char b; }
new Foo[n];

এটি হ'ল, সম্ভবত তিনি "আমি ম্যালোক ব্যবহার করি" বলছেন , তবে এর অর্থ "আমি স্ট্রাক ব্যবহারের পরিবর্তে স্বাক্ষরিত অবস্থানগুলিতে ম্যানুয়ালি ডেটা প্যাক করি" means কাঠামোটি mallocম্যানুয়ালি প্যাক করার জন্য আসলে প্রয়োজন হয় না, তবে তা বুঝতে ব্যর্থ হওয়ায় কম বিভ্রান্তি হয়। তারের মাধ্যমে প্রেরিত ডেটা বিন্যাসটি নির্ধারণ করা প্রয়োজন। ভিন্ন বাস্তবায়নের ইচ্ছা প্যাড তথ্য ভিন্নভাবে যখন struct হয় ব্যবহার করা হয়।


প্রান্তিককরণ সম্পর্কে পয়েন্ট জন্য ধন্যবাদ। প্রশ্নের মধ্যে থাকা ডেটা একটি চর অ্যারে, সুতরাং আমি সন্দেহ করি এটি এখানে কোনও প্রান্তিককরণ জিনিস নয়, না কোনও কাঠামোগত জিনিস - যদিও এটি আমার প্রথম চিন্তাও ছিল।
hcarver

5
@ এইচবিসিডেভ: ভাল charঅ্যারে কখনই প্যাড করা হয় না, সুতরাং ব্যাখ্যা হিসাবে আমি "বিভ্রান্ত" হয়ে থাকব।
স্টিভ জেসোপ

5

আপনার সহকর্মীর new[]/delete[]মনে যাদুর কুকি থাকতে পারে (অ্যারে মুছে ফেলার সময় এটি প্রয়োগকারী তথ্য ব্যবহার করে)। তবে, কোনও সমস্যা হত না যদি ফিরে আসা ঠিকানায় বরাদ্দ শুরু হয় new[](বরাদ্দকারীর বিপরীতে) ব্যবহার করা হত।

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


2
এটিই আমি প্রথম ভেবেছিলাম, "কাঠামোটি তার অংশগুলির যোগফলের চেয়ে বড়" " সম্ভবত এখান থেকেই তাঁর ধারণাটি এসেছে।
hcarver

3

একটি বস্তুর বিন্যাস উপর নির্ভর পারছে না যে এটি ব্যবহার বরাদ্দ ছিল mallocবা new। তারা উভয়ই একই ধরণের পয়েন্টারটি ফেরত দেয় এবং আপনি যখন এই পয়েন্টারটিকে অন্য ফাংশনে পাস করেন তখন তারা বুঝতে পারবেন না কীভাবে বস্তুটি বরাদ্দ করা হয়েছিল। sizeof *ptrএটি কেবল ঘোষণার উপর নির্ভরশীল, এটি ptrকীভাবে বরাদ্দ করা হয়েছিল তা নয়।


3

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


আমি পূর্বে অধিকৃত চাই আপনি বিবেচনা করতে পারে newজন্য একটি চমৎকার মোড়কের যেমন mallocতবে এটি অন্যান্য উত্তরগুলি না থেকে মনে হয় বেশ সত্য। Sensক্যমত্য বলে মনে হয় যে প্যাডিংয়ের সাথে উভয়ই সমান হওয়া উচিত; আমি মনে করি প্ল্যাটফর্মগুলির মধ্যে ডেটা স্থানান্তর করার বিষয়টি কেবল তখনই আসে যখন আপনার স্থানান্তর প্রক্রিয়াটি ত্রুটিযুক্ত :)
hcarver

0

আমি যখন এমএস ভিজ্যুয়াল কম্পাইলারগুলি সহ আমার প্লেইন পুরাতন ডেটা স্ট্রাকচারের লেআউটটি নিয়ন্ত্রণ করতে চাই #pragma pack(1)। আমি মনে করি যে প্রাক-কম্পাইলারের দিকনির্দেশনা বেশিরভাগ সংকলকগুলির জন্য সমর্থনযোগ্য, উদাহরণস্বরূপ জিসিসি

এটি খালি স্থান ব্যতীত কাঠামোর সমস্ত ক্ষেত্রকে একের পিছনে সারিবদ্ধ করার ফলাফল রয়েছে।

অন্য প্রান্তের প্ল্যাটফর্মটি যদি একই কাজ করে (যেমন 1 এর প্যাডিং সহ এটির ডেটা এক্সচেঞ্জ কাঠামো সংকলিত), তবে উভয় পক্ষের জায়েসে প্রাপ্ত ডেটাটি ভাল ফিট করে। এভাবে আমাকে কখনও সি ++ তে ম্যালোকের সাথে খেলতে হয়নি।

সবচেয়ে খারাপভাবে আমি নতুন অপারেটরটিকে ওভারলোডিংয়ের বিষয়টি বিবেচনা করতাম যাতে এটি সি ++ এ সরাসরি ম্যালোক ব্যবহার না করে কিছু জটিল জিনিস সম্পাদন করে।


আপনি ডেটা স্ট্রাকচার লেআউটটি নিয়ন্ত্রণ করতে চান এমন কোন পরিস্থিতিতে রয়েছে? উৎসুক.
hcarver

এবং কেউ কি সংকলক সমর্থনকারী pragma packবা অনুরূপ সম্পর্কে জানেন ? আমি বুঝতে পারি এটি স্ট্যান্ডার্ডের অংশ হবে না।
hcarver

gcc উদাহরণস্বরূপ এটি সমর্থন করে। কোন পরিস্থিতিতে আমার এটির দরকার ছিল: দুটি পৃথক প্লেটফর্মের মধ্যে বাইনারি ডেটা ভাগ করা: উইন্ডো এবং পলমোসের মধ্যে উইন্ডো এবং লিনাক্সের মধ্যে বাইনারি স্ট্রিম ভাগ করে নেওয়া। জিসিসি
স্টিফেন রোল্যান্ড

0

এই জিনিসটি কোথা থেকে আসছে এটিই আমার বুনো অনুমান। যেমনটি আপনি উল্লেখ করেছেন, এমপিআইতে ডেটা সংক্রমণে সমস্যা রয়েছে।

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

উদাহরণস্বরূপ, যদি আপনি std::vector<Foo> Aউল্লিখিত কৌশলটি দিয়ে এমপিআইতে পাঠাতে / গ্রহণ করতে চান , তবে A.size()*sizeof(Foo)সাধারণভাবে চরগুলির ফলাফলের অ্যারের আকার ধরে নেওয়া ভুল হবে । অন্য কথায়, প্রতিটি শ্রেণি যা সিরিয়ালাইজ / ডিসরিয়ালাইজ পদ্ধতি প্রয়োগ করে, এমন একটি পদ্ধতিও প্রয়োগ করা উচিত যা অ্যারের আকারের প্রতিবেদন করে (বা আরও ভাল এখনও পাত্রে অ্যারে সংরক্ষণ করে)। এটি বাগের পিছনে কারণ হতে পারে। তবে একটি উপায় বা অন্য newকোনওভাবে mallocএই থ্রেডে নির্দেশিত বনামের সাথে কোনও সম্পর্ক নেই ।


চরের অ্যারে অনুলিপি করা সমস্যাযুক্ত হতে পারে - এটি সম্ভব আপনার কয়েকটি কোর ছোট-এন্ডিয়ান আর্কিটেকচারে রয়েছে এবং কিছু বিগ-এন্ডিয়ান (সম্ভবত সম্ভাব্য নয়, তবে সম্ভব)। আপনাকে এগুলি বা অন্য কিছু এক্সডিআর-এনকোড করতে হবে তবে আপনি কেবল ব্যবহারকারী-সংজ্ঞায়িত এমপিআই ডেটাটাইপগুলি ব্যবহার করতে পারেন। তারা সহজেই প্যাডিংয়ের অ্যাকাউন্ট নেয়। তবে আমি বুঝতে পারি যে আপনি ভুল বোঝাবুঝির সম্ভাব্য কারণ সম্পর্কে যা বলছেন - এটিই আমি "স্ট্রাক্টটিকে তার অংশগুলির যোগফলের চেয়ে বড়তর" সমস্যা বলছি।
hcarver

হ্যাঁ, এমপিআই ডেটা টাইপগুলি সংজ্ঞায়িত করা এটি করার আরেকটি সঠিক / সঠিক উপায়। শেষ সম্পর্কে ভাল পয়েন্ট। যদিও, আমি সত্যিই সন্দেহ করি যে এটি প্রকৃত ক্লাস্টারগুলিতে ঘটবে। যাইহোক, আমি ভেবেছিলাম তারা যদি একই কৌশল অবলম্বন করে তবে এটি বাগের দিকে নিয়ে যেতে পারে ...
মিমিরজাদেহ

0

সি ++ তে: new কীওয়ার্ডটি কিছু ডেটা-কাঠামোর ক্ষেত্রে মেমরির নির্দিষ্ট কিছু বাইট বরাদ্দ করতে ব্যবহৃত হয়। উদাহরণস্বরূপ, আপনি কিছু শ্রেণি বা কাঠামো সংজ্ঞায়িত করেছেন এবং আপনি এটির জন্য মেমরি বরাদ্দ করতে চান।

myclass *my = new myclass();

অথবা

int *i = new int(2);

তবে সমস্ত ক্ষেত্রে আপনার সংজ্ঞায়িত ডেটাটাইপ (শ্রেণি, কাঠামো, ইউনিয়ন, আন্ত, চর ইত্যাদি ...) প্রয়োজন এবং কেবলমাত্র মেমরির বাইটগুলি বরাদ্দ করা হবে যা তার অবজেক্ট / ভেরিয়েবলের জন্য প্রয়োজনীয়। (যেমন; সেই ডেটাটাইপের গুণক)।

তবে malloc () পদ্ধতির ক্ষেত্রে আপনি কোনও মেমরির বাইট বরাদ্দ করতে পারেন এবং আপনাকে সর্বদা ডেটা টাইপ নির্দিষ্ট করার দরকার নেই। এখানে আপনি এটি malloc () এর কয়েকটি সম্ভাবনায় পর্যবেক্ষণ করতে পারেন:

void *v = malloc(23);

অথবা

void *x = malloc(sizeof(int) * 23);

অথবা

char *c = (char*)malloc(sizeof(char)*35);

-1

মলোক হ'ল একধরণের ফাংশন এবং নতুন প্রকারের সি ++ তে ডাটা টাইপ, যদি আমরা আমাদের প্রয়োজনের তুলনায় ম্যালোক ব্যবহার করি এবং টাইপকাস্ট ব্যবহার করা উচিত অন্যথায় সংকলক আপনাকে ত্রুটি দেয় এবং যদি আমরা প্রয়োজনের তুলনায় মেমরি বরাদ্দের জন্য নতুন ডেটা টাইপ ব্যবহার করি টাইপকাস্ট করতে


1
আমি মনে করি আপনার উত্তরটি আরও কিছুটা যুক্তি দেওয়ার চেষ্টা করা উচিত।
কার্লো

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