এই প্রতিমাটি স্বাভাবিকভাবেই 1 ডি অ্যারে বরাদ্দের বাইরে পড়ে। আসুন কিছু স্বেচ্ছাচারী ধরণের 1D অ্যারে বরাদ্দ দিয়ে শুরু করি T
:
T *p = malloc( sizeof *p * N );
সরল, তাই না? অভিব্যক্তি *p
টাইপ হয়েছে T
তাই হয়, sizeof *p
হিসাবে একই ফলাফল দেয় sizeof (T)
, তাই আমরা একটি জন্য পর্যাপ্ত স্থান বণ্টন করছেন N
এর -element অ্যারে T
। এটি যে কোনও ধরণেরT
ক্ষেত্রে সত্য ।
এখন, এর T
মতো একটি অ্যারের সাথে প্রতিস্থাপন করা যাক R [10]
। তারপরে আমাদের বরাদ্দ হয়ে যায়
R (*p)[10] = malloc( sizeof *p * N);
এখানকার শব্দার্থবিজ্ঞান 1 ডি বরাদ্দ পদ্ধতির সাথে হুবহু ; সমস্ত পরিবর্তিত হয় এর ধরণ p
। পরিবর্তে T *
, এটি এখন R (*)[10]
। এক্সপ্রেশনতে *p
টাইপ রয়েছে T
যা টাইপ R [10]
, তাই sizeof *p
সমান sizeof (T)
যা সমান sizeof (R [10])
। সুতরাং আমরা একটি উপাদান অ্যারের N
দ্বারা পর্যাপ্ত স্থান বরাদ্দ করছি । 10
R
আমরা চাইলে এটিকে আরও এগিয়ে নিতে পারি; ধরুন R
এটি নিজেই একটি অ্যারে টাইপ int [5]
। যে জন্য বিকল্প R
এবং আমরা পেতে
int (*p)[10][5] = malloc( sizeof *p * N);
একই চুক্তি - sizeof *p
হিসাবে একই sizeof (int [10][5])
, এবং আমরা মেমরি বড় যথেষ্ট সংলগ্ন অঞ্চলে বণ্টন একটি রাখা গুটান N
দ্বারা 10
দ্বারা 5
অ্যারে int
।
সুতরাং যে বরাদ্দ দিক; এক্সেস পাশ সম্পর্কে কি?
মনে রাখবেন যে []
সাবস্ক্রিপ্ট অপারেশন করা হয় সংজ্ঞায়িত পয়েন্টার এরিথমেটিক পরিপ্রেক্ষিতে: a[i]
হিসাবে সংজ্ঞায়িত করা হয় *(a + i)
1 । সুতরাং, সাবস্ক্রিপ্ট অপারেটর []
সুস্পষ্টভাবে একটি পয়েন্টার dereferences। যদি p
পয়েন্টার T
হয় তবে আপনি আনারি *
অপারেটরের সাথে সুস্পষ্টভাবে ডিফারেন্সিং করে পয়েন্ট-টু মানটি অ্যাক্সেস করতে পারবেন :
T x = *p;
বা[]
সাবস্ক্রিপ্ট অপারেটর ব্যবহার করে :
T x = p[0]; // identical to *p
সুতরাং, যদি p
কোনও অ্যারের প্রথম উপাদানটিকে নির্দেশ করে তবে আপনি পয়েন্টারে সাবস্ক্রিপ্ট ব্যবহার করে সেই অ্যারের কোনও উপাদান অ্যাক্সেস করতে পারবেন p
:
T arr[N];
T *p = arr; // expression arr "decays" from type T [N] to T *
...
T x = p[i]; // access the i'th element of arr through pointer p
এখন, আবার আমাদের প্রতিস্থাপন অপারেশন করা যাক এবং T
অ্যারের টাইপ সঙ্গে প্রতিস্থাপন R [10]
:
R arr[N][10];
R (*p)[10] = arr; // expression arr "decays" from type R [N][10] to R (*)[10]
...
R x = (*p)[i];
এক সঙ্গে সঙ্গে স্পষ্ট পার্থক্য; p
সাবস্ক্রিপ্ট অপারেটর প্রয়োগের আগে আমরা স্পষ্টতই dereferences করছি । আমরা এতে সাবস্ক্রিপ্ট করতে চাই না p
, আমরা কী p
পয়েন্টগুলিতে সাবস্ক্রিপ্ট করতে চাই (এই ক্ষেত্রে অ্যারে arr[0]
)। যেহেতু ইউনারী *
সাবস্ক্রিপ্ট কম প্রাধান্য রয়েছে []
অপারেটর, আমরা স্পষ্টভাবে গ্রুপে প্রথম বন্ধনী ব্যবহার করতে হবে p
সঙ্গে *
। তবে উপরে থেকে মনে রাখবেন যে *p
এটি একই p[0]
, তাই আমরা এটির সাথে বিকল্পটি পারি
R x = (p[0])[i];
বা শুধু
R x = p[0][i];
সুতরাং, যদি p
একটি 2 ডি অ্যারের দিকে নির্দেশ করে, আমরা সেইরকম মাধ্যমে অ্যারেতে সূচক করতে পারি p
:
R x = p[i][j]; // access the i'th element of arr through pointer p;
// each arr[i] is a 10-element array of R
এটি উপরের মত একই উপসংহারে নিয়ে যাওয়া এবং এর সাথে প্রতিস্থাপন R
করা int [5]
:
int arr[N][10][5];
int (*p)[10][5]; // expression arr "decays" from type int [N][5][10] to int (*)[10][5]
...
int x = p[i][j][k];
এটি ঠিক একইভাবে কাজ করে যদি p
কোনও নিয়মিত অ্যারেতে নির্দেশ করে, বা এটি যদি বরাদ্দকৃত স্মৃতিতে নির্দেশ করে malloc
।
এই প্রতিবাদটির নিম্নলিখিত সুবিধা রয়েছে:
- এটি সহজ - টুকরোচর বরাদ্দ পদ্ধতির বিপরীতে কোডের কেবল একটি লাইন
T **arr = malloc( sizeof *arr * N );
if ( arr )
{
for ( size_t i = 0; i < N; i++ )
{
arr[i] = malloc( sizeof *arr[i] * M );
}
}
- বরাদ্দ করা অ্যারের সমস্ত সারি হ'ল * সংযুক্ত *, যা উপরের টুকরাফল বরাদ্দ পদ্ধতির ক্ষেত্রে নয়;
- একক কল করার সাথে অ্যারেটি হ্রাস করা ঠিক তত সহজ
free
। আবার, টুকরোয়াল বরাদ্দ পদ্ধতির সাথে সত্য নয়, যেখানে আপনাকে ডিঅলোকেট করার arr[i]
আগে আপনাকে প্রতিটি ডিএলোকট করতে হবে arr
।
কখনও কখনও টুকরোয়াল বরাদ্দকরণ পদ্ধতি পছন্দনামূলক, যেমন আপনার গাদা খারাপভাবে খণ্ডিত হয়ে গেলে এবং আপনি আপনার স্মৃতিটিকে একটি স্বচ্ছ অংশ হিসাবে বরাদ্দ করতে পারবেন না বা আপনি একটি "জেগড" অ্যারে বরাদ্দ করতে চান যেখানে প্রতিটি সারির আলাদা দৈর্ঘ্য থাকতে পারে। তবে সাধারণভাবে, এটি যাওয়ার আরও ভাল উপায়।
1. মনে রাখবেন অ্যারেগুলি পয়েন্টার নয় - পরিবর্তে অ্যারের এক্সপ্রেশনগুলি প্রয়োজনীয় হিসাবে পয়েন্টার এক্সপ্রেশনগুলিতে রূপান্তরিত হয়।