সাইজে_টি কি?


626

আমি size_tসি-তে বিভ্রান্ত হয়ে যাচ্ছি আমি জানি যে এটি sizeofঅপারেটর ফিরিয়ে দিয়েছে । কিন্তু ঠিক এটা কি? এটি কি কোনও ডেটা টাইপ?

ধরা যাক আমার একটি forলুপ আছে:

for(i = 0; i < some_size; i++)

আমার ব্যবহার করা উচিত int i;নাকি size_t i;?


11
সেই আপনার একমাত্র অপশন হন, ব্যবহার intযদি some_sizeসাইন করা হয়েছে, size_tযদি এটা স্বাক্ষরবিহীন করা হয়।
Nate

8
@ নাট এটি ভুল। পসিক্সের একটি সাইজ_টি টাইপ রয়েছে তবে ব্যবহারের জন্য প্রকৃত সঠিক টাইপটি হল ptrdiff_t।
স্টিভেন স্টুয়ার্ট-গ্যালাস

2
উত্তরগুলি নিম্ন-স্তরের প্রোগ্রামিংয়ের মতো পরিষ্কার নয় : সি, অ্যাসেমব্লি এবং ইন্টেল ®৪ তে প্রোগ্রাম এক্সিকিউশন । বইটিতে যেমন বলা হয়েছে, একটি সূচক ব্যবহার int iকরা বিশাল অ্যারে সম্বোধন করার জন্য যথেষ্ট নাও হতে পারে। সুতরাং ব্যবহার করে size_t iআপনি আরও সূচকগুলিকে সম্বোধন করতে পারেন, তাই আপনার কাছে যদি একটি বিশাল অ্যারে থাকে তবে কোনও সমস্যা হওয়া উচিত নয়। size_tএটি একটি ডেটা টাইপ: সাধারণত একটি unsigned long intতবে এটি আপনার সিস্টেমে নির্ভর করে।
ব্রুনো

উত্তর:


461

উইকিপিডিয়া থেকে :

1999 এর আইএসও সি স্ট্যান্ডার্ড (সি 99) অনুসারে, size_tস্বাক্ষরযুক্ত স্বাক্ষর পূর্ণসংখ্যা কমপক্ষে 16 বিটের (বিভাগ 7.17 এবং 7.18.3 দেখুন)।

size_tবেশ কয়েকটি সি / সি ++ স্ট্যান্ডার্ড দ্বারা সংজ্ঞায়িত একটি স্বাক্ষরযুক্ত ডেটা টাইপ, উদাহরণস্বরূপ C99 আইএসও / আইইসি 9899 স্ট্যান্ডার্ড, যা সংজ্ঞায়িত করা হয়েছে stddef.h1stdlib.h এই ফাইলটি অন্তর্ভুক্ত করে অন্তর্ভুক্ত করে অন্তর্ভুক্ত করে এটি আরও আমদানি করা যেতে পারে stddef.h

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

অন্তর্নিহিত হিসাবে, size_tকোনও ধরণের সূচি রাখার গ্যারান্টিযুক্ত type


4
"লাইব্রেরির ফাংশনগুলি যা মাপ দেয় বা ফেরত দেয় তারা প্রত্যাশিত ... আকার_t" ব্যতীত স্ট্যাট () ফাইলের আকারের জন্য অফ_টি ব্যবহার করে
ড্রিমন

64
@ ড্রেমন মন্তব্যটি একটি মৌলিক বিভ্রান্তির প্রতিফলন করে। size_tস্মৃতিতে বস্তুর জন্য। সি স্ট্যান্ডার্ড এমনকি সংজ্ঞায়িত করে না stat()বা off_t(সেগুলি পসিক্স সংজ্ঞাগুলি) বা ডিস্ক বা ফাইল সিস্টেমগুলির সাথে করার মতো কোনও কিছুই নেই - এটি FILEস্ট্রিমে নিজেকে থামিয়ে দেয় । ভার্চুয়াল মেমরি পরিচালনা ফাইলের আকার এবং ফাইল ম্যানেজমেন্টের থেকে আকারের প্রয়োজনীয়তাগুলি থেকে সম্পূর্ণ আলাদা, সুতরাং off_tএখানে উল্লেখ অপ্রাসঙ্গিক।
jw013

3
@ jw013: আমি এটিকে কষ্টের সাথে একটি মৌলিক বিভ্রান্তি বলব না, তবে আপনি একটি আকর্ষণীয় বিষয় বানাচ্ছেন। তবুও, উদ্ধৃত পাঠ্যটি "মেমরি ইন মেমরি অবজেক্টস" বলে না, এবং "অফসেট" আকারের আকারের জন্য এটি সঞ্চিত হওয়ার কারণ নির্বিশেষে খুব কমই ভাল নাম নয়।
ড্রইমন

30
@ ড্রামন ভালো পয়েন্ট এই উত্তরটি উইকিপিডিয়াকে উদ্ধৃত করে, যা এই ক্ষেত্রে আমার মতে সর্বোত্তম ব্যাখ্যা দেয় না। সি স্ট্যান্ডার্ড নিজেই আরও স্পষ্ট: এটি অপারেটরের size_tফলাফলের ধরণ হিসাবে sizeof(প্রায় 7.17 পি 2 <stddef.h>) হিসাবে সংজ্ঞায়িত করে । বিভাগ 6.5 ব্যাখ্যা করে যে সি এক্সপ্রেশনগুলি ঠিক কীভাবে কাজ করে (6.5.3.4 এর জন্য sizeof)। যেহেতু আপনি sizeofডিস্ক ফাইলে আবেদন করতে পারবেন না (বেশিরভাগ কারণ সি এমনকি ডিস্ক এবং ফাইলগুলি কীভাবে কাজ করে তা নির্ধারণ করে না), বিভ্রান্তির কোনও স্থান নেই room অন্য কথায়, উইকিপিডিয়াকে দোষ দিন (এবং উইকিপিডিয়া উদ্ধৃত করার জন্য এই উত্তর এবং আসল সি মান নয়)
jw013

2
@ ড্রেমন - আমি "মৌলিক বিভ্রান্তি" মূল্যায়নের সাথেও একমত হব। আপনি যদি সি / সি ++ স্ট্যান্ডার্ডটি না পড়ে থাকেন তবে আপনি মনে করতে পারেন যে "অবজেক্ট" "অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিং," যা এটি না তা বোঝায়। সি স্ট্যান্ডার্ডটি পড়ুন, যার কোনও ওওপি অবজেক্ট নেই, তবে এখনও অবজেক্ট রয়েছে এবং এটি সন্ধান করুন। উত্তরটি তোমাকে চমকে দিতে পারে!
হান্টিকুট

220

size_tস্বাক্ষরবিহীন প্রকার। সুতরাং, এটি কোনও নেতিবাচক মানকে উপস্থাপন করতে পারে না (<0)। আপনি কোনও কিছু গণনা করার সময় আপনি এটি ব্যবহার করেন এবং নিশ্চিত হন যে এটি নেতিবাচক হতে পারে না। উদাহরণস্বরূপ, strlen()একটি প্রদান করে size_tকারণ একটি স্ট্রিংয়ের দৈর্ঘ্য কমপক্ষে 0 হতে হবে।

আপনার উদাহরণস্বরূপ, যদি আপনার লুপ সূচকটি সর্বদা 0 এর চেয়ে বড় হয়, তবে এটি ব্যবহার করা size_tবা অন্য কোনও স্বাক্ষরযুক্ত ডেটা টাইপটি বোধগম্য হতে পারে ।

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

size_t s1 = strlen(str1);
size_t s2 = strlen(str2);

এবং আপনার লেন্থ পার্থক্য খুঁজে পেতে চান str2এবংstr1 । আপনি করতে পারবেন না:

int diff = s2 - s1; /* bad */

এর কারণ হ'ল নির্ধারিত মান diffসর্বদা একটি ধনাত্মক সংখ্যা হতে চলেছে, এমনকি যখন s2 < s1, গণনা স্বাক্ষরযুক্ত প্রকারের সাথে সম্পন্ন করা হয়। এই ক্ষেত্রে, আপনার ব্যবহারের কেসের উপর নির্ভর করে আপনি এবং এর জন্য int(বা long long) ব্যবহার করা ভাল ।s1s2

সি / পসিক্সে কিছু ফাংশন রয়েছে যা ব্যবহার করতে পারে / করা উচিত size_t, তবে historicalতিহাসিক কারণে নয়। উদাহরণস্বরূপ, দ্বিতীয় প্যারামিটারটি fgetsআদর্শভাবে হওয়া উচিত size_t, তবে তা int


8
@ অলোক: দুটি প্রশ্ন: ১) আকার কত size_t? ২) কেন আমার পছন্দ size_tমতো কিছু করা উচিত unsigned int?
লেজার

2
@Lazer: আকার size_tহল sizeof(size_t)। সি স্ট্যান্ডার্ড গ্যারান্টি দেয় যা SIZE_MAXকমপক্ষে 65535 হবে 35 size_tপ্রকারটি sizeofঅপারেটর দ্বারা ফিরিয়ে দেওয়া হয় , এবং এটি স্ট্যান্ডার্ড লাইব্রেরিতে ব্যবহৃত হয় (উদাহরণস্বরূপ strlenরিটার্ন size_t)। ব্রেন্ডন যেমন বলেছিল, size_tতেমন হওয়ার দরকার নেই unsigned int
অলোক সিংহল

4
@ লেজার - হ্যাঁ, size_tএকটি স্বাক্ষরবিহীন প্রকারের গ্যারান্টিযুক্ত।
অলোক সিংহল

2
@ চেরিটারাস না, আমি বোঝাতে চাইছি যে স্বাক্ষরবিহীন প্রকারটি কেবল অ-নেতিবাচক মানগুলিকে উপস্থাপন করতে পারে। আমার সম্ভবত বলা উচিত ছিল "এটি নেতিবাচক মানগুলি উপস্থাপন করতে পারে না"।
অলোক সিংহল

4
@ জেসনঅস্টার, দু'টির পরিপূরক সি স্ট্যান্ডার্ডের প্রয়োজন হয় না। যদি s2 - s1ওভারফ্লো একটি এর মান হয় intতবে আচরণটি সংজ্ঞায়িত হয়।
অলোক সিংহল

73

size_t এমন একটি ধরন যা কোনও অ্যারে সূচক ধরে রাখতে পারে।

বাস্তবায়নের উপর নির্ভর করে এটি যে কোনও একটি হতে পারে:

unsigned char

unsigned short

unsigned int

unsigned long

unsigned long long

আমার মেশিনে size_tএটি কীভাবে সংজ্ঞায়িত করা হয়েছে তা এখানে stddef.h:

typedef unsigned long size_t;

4
অবশ্যই typedef unsigned long size_tসংকলক নির্ভর। বা আপনি কি সবসময় এমন পরামর্শ দিচ্ছেন?
chux

4
@ চাক্স: আসলেই, কারণ একটি বাস্তবায়ন এটিকে এরূপ হিসাবে সংজ্ঞায়িত করে, এর অর্থ সমস্ত কিছু হয় না। ক্ষেত্রে পয়েন্ট: -৪-বিট উইন্ডোজ। unsigned long32-বিট হয়, size_t64-বিট হয়।
টিম

2
মাপের উদ্দেশ্য ঠিক কী? যখন আমি নিজের জন্য একটি পরিবর্তনশীল তৈরি করতে পারি: "int mysize_t;" বা "দীর্ঘ মাইজাইজ_টি" বা "স্বাক্ষরযুক্ত দীর্ঘ মাইজাইজ_টি"। আমার জন্য কেন এই পরিবর্তনশীলটি তৈরি করা উচিত?
মিডকিন

1
@ মিডকিন size_tকোনও পরিবর্তনশীল নয়। এটি মেমরির কোনও বস্তুর আকার উপস্থাপন করতে চাইলে আপনি এটি ব্যবহার করতে পারেন।
অর্জুন শ্রীধরন

1
এটি কি সত্য যে size_t32-বিট মেশিনে সর্বদা 32 বিট থাকে, একইভাবে bits৪ বিট?
জন উ

70

আপনি যদি অভিজ্ঞতা অভিজ্ঞতা হয় ,

echo | gcc -E -xc -include 'stddef.h' - | grep size_t

উবুন্টু 14.04 64-বিট জিসিসি 4.8 এর আউটপুট:

typedef long unsigned int size_t;

নোট যে stddef.hজিসিসি দ্বারা সরবরাহ করা হয়েছে এবং গিসিবিসি নয় src/gcc/ginclude/stddef.hজিসিসি ৪.২ এর আওতায় ।

আকর্ষণীয় C99 উপস্থিতি

  • mallocsize_tআর্গুমেন্ট হিসাবে গ্রহণ করে , তাই এটি বরাদ্দ হওয়া সর্বাধিক আকার নির্ধারণ করে।

    এবং যেহেতু এটিও ফিরে এসেছে sizeof , আমি মনে করি এটি কোনও অ্যারের সর্বাধিক আকারকে সীমাবদ্ধ করে।

    আরও দেখুন: সিটিতে একটি অ্যারের সর্বাধিক আকার কত?


1
আমার একই পরিবেশ রয়েছে, তবে আমি এটি 32 বিটের জন্য পরীক্ষা করেছি, জিসিসির "-m32" বিকল্পটি পাস করে, ফলাফলটি ছিল: "টাইপফেফ স্বাক্ষরবিহীন ইন্ট সাইজ_টি"। এই দুর্দান্ত কমান্ড @ সিরো ভাগ করে নেওয়ার জন্য ধন্যবাদ, এটি আমাকে অনেক সাহায্য করেছে! :-)
সিলভিপ্রোগ

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

1
দুর্দান্ত উত্তর, কারণ এটি আপনাকে আসলে কমপক্ষে একটি জনপ্রিয় লিনাক্স ডিস্ট্রোতে কী size_tতা বলে দেয় ।
অ্যান্ড্রে পোর্টনয়

25

জন্য র manpage types.h বলেছেন:

আকার_t একটি স্বাক্ষরবিহীন পূর্ণসংখ্যার প্রকার হবে


19

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


আমার প্রশ্ন সবসময়ই ছিল: যদি আকারের অস্তিত্ব কখনও না থাকে, তবে আকার_টি দরকার হবে?
ডিন পি

@ ডিয়ানপি: সম্ভবত তা না, যদিও এরপরে এমন কোনও প্রশ্ন রয়েছে যা পছন্দসই জিনিসের জন্য কী যুক্তির ধরণটি ব্যবহার করা উচিত malloc()। ব্যক্তিগতভাবে, আমি দেখেছি সংস্করণ কোন ধরনের অফ আর্গুমেন্ট নিতে পছন্দ করতাম int, longআর long longকিছু বাস্তবায়নের বাস্তবায়নে যেমন খাটো ধরনের এবং অন্যদের তুলে ধরার সঙ্গে, lmalloc(long n) {return (n < 0 || n > 32767) ? 0 : imalloc(n);}[কিছু প্ল্যাটফর্মের উপর, কলিং করার imalloc(123)আহ্বান তুলনায় সস্তা হবে lmalloc(123);, এবং এমনকি একটি প্ল্যাটফর্ম যেখানে উপর size_t16 বিটস, কোড যা একটি `দীর্ঘ` মানের মধ্যে গণনা করা আকারটি বরাদ্দ করতে চায় ...
সুপারক্যাট

... যদি বরাদ্দকারী হ্যান্ডেল করতে পারে তার চেয়ে বড় হয় তবে বরাদ্দকে ব্যর্থ করার উপর নির্ভর করতে সক্ষম হওয়া উচিত।
সুপারক্যাট

11

কেন size_tএখানে থাকা দরকার এবং কীভাবে আমরা এখানে এলাম তা জানার জন্য:

ব্যবহারিক দিক থেকে size_tএবং a৪ ptrdiff_tবিট প্রয়োগের ক্ষেত্রে b৪ বিট প্রশস্ত, 32-বিট বাস্তবায়নে 32 বিট প্রস্থ এবং এই জাতীয় গ্যারান্টিযুক্ত। উত্তরাধিকারের কোডটি ভঙ্গ না করে তারা প্রতিটি সংকলকটিতে বিদ্যমান কোনও প্রকারকে বোঝাতে বাধ্য করতে পারেনি।

size_tবা ptrdiff_tঅগত্যা একটি intptr_tবা হিসাবে একই হয় না uintptr_t। তারা নির্দিষ্ট আর্কিটেকচারের যে এখনও ব্যবহৃত ছিল বিভিন্ন ছিল size_tএবং ptrdiff_tপ্রয়াত '80s মধ্যে স্ট্যান্ডার্ড যোগ করা হয় নি, এবং অপ্রচলিত হয়ে উঠছে যখন C99 অনেক নতুন ধরনের যোগ কিন্তু এখনও সরানো হয়নি (যেমন 16 বিট উইন্ডোজ হিসাবে)। 16-বিট সুরক্ষিত মোডে x86 এর একটি বিভাগযুক্ত মেমরি ছিল যেখানে বৃহত্তম সম্ভাব্য অ্যারে বা কাঠামো মাত্র 65,536 বাইট আকারের হতে পারে, তবে farরেজিস্টারগুলির চেয়ে 32 বিট প্রশস্ত, পয়েন্টার হওয়া দরকার। ঐ তারিখে, intptr_t32 বিট প্রশস্ত হতো কিন্তু size_tএবংptrdiff_t16 বিট প্রশস্ত এবং একটি রেজিস্টারে ফিট হতে পারে। এবং ভবিষ্যতে কোন ধরণের অপারেটিং সিস্টেম লিখিত হতে পারে কে জানত? তত্ত্ব অনুসারে, আই 386 আর্কিটেকচারটি 48-বিট পয়েন্টার সহ 32-বিট সেগমেন্টেশন মডেল সরবরাহ করে যা কোনও অপারেটিং সিস্টেম আসলে ব্যবহার করেনি।

অফসেটের মেমরির ধরণটি longকারণ হতে পারে না কারণ অনেক বেশি লিগ্যাসি কোডটি ধরে নিয়েছে যে long32 বিট বিস্তৃত। এই অনুমানটি এমনকি ইউএনআইএক্স এবং উইন্ডোজ এপিআইতে নির্মিত হয়েছিল। দুর্ভাগ্যক্রমে, প্রচুর অন্যান্য লিগ্যাসি কোডও ধরে নিয়েছে যে longপয়েন্টার, ফাইল অফসেট, সেকেন্ডের সংখ্যা যে ১৯ 1970০ সাল থেকে পেরিয়ে গেছে, ধরে রাখার জন্য যথেষ্ট প্রশস্ত। পজিক্স এখন পূর্বের পরিবর্তে পরবর্তী ধারণাটি সত্য হতে বাধ্য করার জন্য একটি প্রমিত মানের উপায় সরবরাহ করে তবে কোনওটিই বহনযোগ্য পোর্টেবল অনুমান নয়।

এটি হতে পারে না intকারণ 90 এর দশকে কেবলমাত্র একটি ক্ষুদ্র মুষ্টিমেয় সংকলক int64 বিট প্রশস্ত করেছিলেন। তারপরে long32 বিট প্রশস্ত রেখে তারা সত্যিই অদ্ভুত হয়ে উঠল । স্ট্যান্ডার্ডের পরবর্তী সংশোধনটি এর intচেয়ে বেশি বিস্তৃত হওয়ার জন্য এটি অবৈধ ঘোষণা করেছে long, তবে intবেশিরভাগ 64-বিট সিস্টেমে 32 বিট প্রস্থ রয়েছে।

এটি হতে পারে না long long int, যা যাইহোক পরে যুক্ত করা হয়েছিল, যেহেতু এটি 32-বিট সিস্টেমে কমপক্ষে 64 বিট প্রশস্ত হতে তৈরি হয়েছিল।

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


"এর সাথে অসম্মতি size_tএবং 64৪ ptrdiff_tবিট প্রয়োগের ক্ষেত্রে be৪ বিট প্রশস্ত হওয়ার গ্যারান্টি দেওয়া হয় " ইত্যাদি গ্যারান্টিটি বাড়িয়ে দেওয়া হয়েছে। এর ব্যাপ্তি size_tপ্রাথমিকভাবে বাস্তবায়নের মেমরির ক্ষমতা দ্বারা চালিত হয়। "একটি এন-বিট বাস্তবায়ন" মূলত পূর্ণসংখ্যার নেটিভ প্রসেসরের প্রস্থ। অবশ্যই অনেকগুলি বাস্তবায়ন একই আকারের মেমরি এবং প্রসেসরের বাসের প্রস্থ ব্যবহার করে, তবে প্রচুর মেমরির সাথে স্ক্যান্ট মেমরি বা সংকীর্ণ প্রসেসরের বিস্তৃত নেটিভ ইন্টিজার বিদ্যমান এবং এই দুটি বাস্তবায়ন বৈশিষ্ট্যকে পৃথক করে দেয়।
chux -

8

size_tএবং intবিনিময়যোগ্য নয়। উদাহরণস্বরূপ 64৪-বিট লিনাক্সের size_tআকার 64৪-বিট হয় (যেমন sizeof(void*)) তবে intএটি 32-বিট।

এছাড়াও size_tস্বাক্ষর করুন যে নোট । আপনার যদি স্বাক্ষরিত সংস্করণ দরকার ssize_tহয় তবে কিছু প্ল্যাটফর্ম রয়েছে এবং এটি আপনার উদাহরণের সাথে আরও প্রাসঙ্গিক হবে।

একটি সাধারণ নিয়ম অনুযায়ী আমি ব্যবহার সুপারিশ করবে intসবচেয়ে সাধারণ মামলা এবং শুধুমাত্র ব্যবহার size_t/ ssize_tযখন (সঙ্গে এটি জন্য কোনো সুনির্দিষ্ট প্রয়োজন নেই mmap()উদাহরণস্বরূপ)।


3

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


3
আমি আপনার যুক্তি গ্রহণ করতে পারি না। আপনি বলছেন যে ওভারফ্লো বাগটি চুপচাপ আপনার অ্যারের মধ্যে বৈধ ডেটা অ্যাক্সেসের দিকে পরিচালিত করে?
মাফ-সফট

1
@ মাফ-সফট সঠিক। ত্রুটিটি যদি সনাক্ত না হয় তবে এটি প্রোগ্রাম ক্রাশের চেয়ে খারাপ করে তোলে। কেন এই উত্তর upvotes পেল?
yoyo_fun 21 '11

যদি এটি আপনার অ্যারেতে বৈধ ডেটা অ্যাক্সেস করে তবে এটি কোনও বাগ নয় কারণ স্বাক্ষরযুক্ত প্রকারটি স্বাক্ষরিত সীমাতে সীমাবদ্ধভাবে প্রবাহিত হবে না। এই যুক্তি ছেলেরা কি? আসুন কোনও কারণে আপনি 256 এলিমেন্ট অ্যারের উপরে পুনরাবৃত্তি করতে চর ব্যবহার করুন ... স্বাক্ষরিত 127 এ ওভারফ্লো হবে এবং 128 তম উপাদান সিগসেগভ হবে, তবে আপনি স্বাক্ষরবিহীন ব্যবহার করেন, তবে এটি উদ্দেশ্য হিসাবে পুরো অ্যারেতে যাবে। তারপরে আবার, যখন আপনি কোনও ইনট ব্যবহার করছেন, আপনার অ্যারেগুলি 2 বিলিয়ন উপাদানের চেয়ে বেশি বড় হবে না তাই যেভাবেই এটি কোনও বিষয় নয় ...
বেগুনি আইস

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

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

3

সাইজ_টি স্বাক্ষরযুক্ত পূর্ণসংখ্যার ডেটা টাইপ। জিএনইউ সি লাইব্রেরি ব্যবহার করে এমন সিস্টেমে এটি স্বাক্ষরযুক্ত স্বাক্ষরিত বা স্বাক্ষরবিহীন দীর্ঘ অন্তর্নিহিত হবে। আকার_t সাধারণত অ্যারে সূচক এবং লুপ গণনার জন্য ব্যবহৃত হয়।


1

সাইজ_টি বা কোনও স্বাক্ষরবিহীন টাইপ লুপ ভেরিয়েবল হিসাবে ব্যবহৃত হতে পারে কারণ লুপ ভেরিয়েবলগুলি সাধারণত 0 এর চেয়ে বড় বা সমান হয়।

যখন আমরা একটি আকার_আউট অবজেক্টটি ব্যবহার করি তখন আমাদের তা নিশ্চিত করতে হবে পাটিগণিত সহ সমস্ত প্রসঙ্গে এটি ব্যবহৃত হয়, আমরা কেবল অ-নেতিবাচক মান চাই। উদাহরণস্বরূপ, নিম্নলিখিত প্রোগ্রামটি অবশ্যই অপ্রত্যাশিত ফলাফল দেবে:

// C program to demonstrate that size_t or
// any unsigned int type should be used 
// carefully when used in a loop

#include<stdio.h>
int main()
{
const size_t N = 10;
int a[N];

// This is fine
for (size_t n = 0; n < N; ++n)
a[n] = n;

// But reverse cycles are tricky for unsigned 
// types as can lead to infinite loop
for (size_t n = N-1; n >= 0; --n)
printf("%d ", a[n]);
}

Output
Infinite loop and then segmentation fault

1

size_tএকটি স্বাক্ষরবিহীন পূর্ণসংখ্যার ডেটা টাইপ যা কেবল 0 এবং 0 এর চেয়ে বেশি পূর্ণসংখ্যার মান নির্ধারণ করতে পারে। এটি যে কোনও বস্তুর আকারের বাইটগুলি পরিমাপ করে এবং sizeofঅপারেটর দ্বারা ফিরে আসে । constএর সিনট্যাক্স উপস্থাপনা size_t, তবে constআপনি প্রোগ্রামটি চালাতে পারবেন না।

const size_t number;

size_tঅ্যারে সূচি এবং লুপ গণনার জন্য নিয়মিত ব্যবহৃত হয়। সংকলক 32-bitহলে এটি কাজ করবে unsigned int। সংকলক 64-bitহলে unsigned long long intএটিও কাজ করবে । size_tসংকলক প্রকারের উপর নির্ভর করে সর্বাধিক আকারের জন্য ।

size_tইতিমধ্যে সংজ্ঞায়িত <stdio.h>হেডার ফাইল, কিন্তু এটি দ্বারা সংজ্ঞায়িত করতে পারেন <stddef.h>, <stdlib.h>, <string.h>, <time.h>, <wchar.h>হেডার।

  • উদাহরণ (সহ const)
#include <stdio.h>

int main()
{
    const size_t value = 200;
    size_t i;
    int arr[value];

    for (i = 0 ; i < value ; ++i)
    {
        arr[i] = i;
    }

    size_t size = sizeof(arr);
    printf("size = %zu\n", size);
}

আউটপুট -: size = 800


  • উদাহরণ (ছাড়া const)
#include <stdio.h>

int main()
{
    size_t value = 200;
    size_t i;
    int arr[value];

    for (i = 0 ; i < value ; ++i)
    {
        arr[i] = i;
    }

    size_t size = sizeof(arr);
    printf("size = %zu\n", size);
}

আউটপুট -: size = 800


-3

আমার বোধগম্যতা থেকে, size_tএকটি unsignedপূর্ণসংখ্যা যার বিট আকারটি দেশীয় আর্কিটেকচারের পয়েন্টার ধরে রাখতে যথেষ্ট বড়।

তাই:

sizeof(size_t) >= sizeof(void*)

16
সত্য না. পয়েন্টারের আকার এর চেয়ে বড় হতে পারে size_t। বেশ কয়েকটি উদাহরণ: x86 রিয়েল মোডে সি সংকলকগুলিতে 32 বিট FARবা HUGEপয়েন্টার থাকতে পারে তবে সাইজ_টি এখনও 16 বিট। অন্য উদাহরণ: ওয়াটকম সি-তে প্রসারিত মেমরির জন্য একটি বিশেষ ফ্যাট পয়েন্টার থাকত যা 48 বিট প্রশস্ত size_tছিল , তবে ছিল না। হার্ভার্ড আর্কিটেকচার সহ এম্বেডড কন্ট্রোলারে আপনার কোনও সম্পর্ক নেই, কারণ উভয়েরই ঠিকানার জায়গাগুলির উদ্বেগ।
প্যাট্রিক Schlüter

1
এবং সেই স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 1572099 /… এ 128 বিট পয়েন্টার এবং 32 বিট সহ এএস / 400 এর আরও উদাহরণ রয়েছেsize_t
প্যাট্রিক শ্লিয়েটার

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