दिलचस्प पोस्ट
LINQ का उपयोग कर संग्रह में सभी ऑब्जेक्ट्स को अपडेट करें फाइल नाम के साथ जावास्क्रिप्ट फाइल सहेजें जांच रहा है कि कोई पायथन पायथन में एक प्रमुख संख्या है जावास्क्रिप्ट के माध्यम से छवि फ़ाइल आकार + आयाम निर्धारित करना? Ninject का उपयोग करने के बारे में सवाल एक नकली और ठूंठ के बीच क्या अंतर है? स्विफ्ट में एक SQLite डाटाबेस तक पहुंच कैसे जांचें कि क्या एक एम्बेडेड एसवीजी दस्तावेज़ एक html पृष्ठ में लोड किया गया है? जावा स्विंग JComponent "size" Android एप्लिकेशन में वर्तमान समय और दिनांक प्रदर्शित करें canvas.toDataURL () SecurityError PHP के साथ बेस यूआरएल कैसे प्राप्त करें? JSON ऑब्जेक्ट स्ट्रिंग से सी # क्लास फ़ाइल को स्वत: जनरेट कैसे करें क्या मैं अजगर में स्ट्रिंग बफ़र को किसी प्रकार की रीडायरेक्ट में रीडायरेक्ट कर सकता हूं? क्या मशीन हैं, जहां sizeof (char)! = 1, या कम से कम CHAR_BIT> 8?

कैसे 'sizeof' (एक सरणी के लिए एक संकेत सूचक) को खोजने के लिए?

सबसे पहले, यह कुछ कोड है:

int main() { int days[] = {1,2,3,4,5}; int *ptr = days; printf("%u\n", sizeof(days)); printf("%u\n", sizeof(ptr)); return 0; } 

क्या सरणी के आकार का पता लगाने का एक तरीका है जो ptr को इंगित कर रहा है (इसके आकार को देने के बजाय, जो कि 32-बिट सिस्टम पर चार बाइट्स है)?

वेब के समाधान से एकत्रित समाधान "कैसे 'sizeof' (एक सरणी के लिए एक संकेत सूचक) को खोजने के लिए?"

नहीं, आप नहीं कर सकते संकलक यह नहीं जानता कि सूचक क्या इंगित कर रहा है इसमें कोई चाल है, जैसे कि ज्ञात आउट-ऑफ-बैंड मान के साथ सरणी को समाप्त करना और फिर उस मूल्य तक आकार को गिनाना, लेकिन वह sizeof का उपयोग नहीं कर रहा है।

एक और चाल है जो ज़ेन द्वारा उल्लिखित है, जो आकार को कहीं और छिपाना है उदाहरण के लिए, यदि आप सरणी को गतिशील रूप से आवंटित कर रहे हैं, तो आपको आवंटित आवंटित ब्लॉक से एक इंट बड़ा आवंटित करें, पहले इंट में आकार छिपाना, और ptr + 1 को सरणी में पॉइंटर के रूप में लौटाएं। जब आपको आकार की आवश्यकता होती है, तो स्टॉश्ड वैल्यू पर सूचक और झांकना घटो। बस शुरुआत से शुरू होने वाले पूरे ब्लॉक को मुक्त करने के लिए याद रखें, और न सिर्फ सरणी।

जवाब न है।"

सी प्रोग्रामर क्या करते हैं, कहीं न कहीं सरणी का आकार संग्रहीत करते हैं यह एक संरचना का हिस्सा हो सकता है, या प्रोग्रामर थोड़ा और malloc () अधिक स्मृति को धोखा दे सकता है अनुरोध की तुलना में सरणी की शुरुआत से पहले लंबाई मान को स्टोर करने के लिए।

डायनामिक एरेज़ ( मॉलोक या सी ++ नया ) के लिए आपको एरे का आकार स्टोर करना होगा जैसा कि दूसरों द्वारा उल्लिखित किया गया है या शायद सरणी प्रबंधक संरचना का निर्माण करना है जो जोड़ना, हटाने, गिनती इत्यादि को संभालता है। दुर्भाग्य से सी ऐसा लगभग साथ ही नहीं करता सी ++ के बाद से आपको मूल रूप से इसे प्रत्येक अलग सरणी प्रकार के लिए बनाना होगा जो आप संचित कर रहे हैं जो बोझिल है यदि आपके पास कई प्रकार के एरे हैं जिन्हें आपको प्रबंधन की आवश्यकता है।

स्थिर arrays के लिए, जैसे कि आपके उदाहरण में, आकार प्राप्त करने के लिए एक सामान्य मैक्रो होता है, लेकिन यह अनुशंसित नहीं है क्योंकि यह जांच नहीं करता कि पैरामीटर वास्तव में एक स्थिर सरणी है। हालांकि मैक्रो वास्तविक कोड में प्रयोग किया जाता है, उदाहरण के लिनक्स कर्नेल हेडर में, हालांकि यह एक नीचे से थोड़ा अलग हो सकता है:

 #if !defined(ARRAY_SIZE) #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0])) #endif int main() { int days[] = {1,2,3,4,5}; int *ptr = days; printf("%u\n", ARRAY_SIZE(days)); printf("%u\n", sizeof(ptr)); return 0; } 

आप इस तरह मैक्रोज़ से सावधान रहने के कारणों के लिए Google कर सकते हैं। सावधान रहे।

यदि संभव हो तो, वेक्टर जैसे सी + + स्टैडीलिब जो कि अधिक सुरक्षित और प्रयोग करने में आसान है।

Sizeof () का उपयोग किए बिना, C ++ टेम्पलेट्स के साथ एक साफ समाधान है निम्न getSize () फ़ंक्शन किसी भी स्थिर सरणी का आकार देता है:

 #include <cstddef> template<typename T, size_t SIZE> size_t getSize(T (&)[SIZE]) { return SIZE; } 

यहां एक foo_t संरचना के साथ एक उदाहरण है:

 #include <cstddef> template<typename T, size_t SIZE> size_t getSize(T (&)[SIZE]) { return SIZE; } struct foo_t { int ball; }; int main() { foo_t foos3[] = {{1},{2},{3}}; foo_t foos5[] = {{1},{2},{3},{4},{5}}; printf("%u\n", getSize(foos3)); printf("%u\n", getSize(foos5)); return 0; } 

आउटपुट:

 3 5 

इस विशिष्ट उदाहरण के लिए, हां, यदि आप टाइप फिफ का इस्तेमाल करते हैं (नीचे देखें)। बेशक, अगर आप इसे इस तरह करते हैं, तो आप SIZEOF_DAYS का उपयोग करने के लिए ठीक ही बंद हो गए हैं, क्योंकि आपको पता है कि संकेतक क्या इंगित कर रहा है।

यदि आपके पास (शून्य *) संकेतक है, जैसा कि malloc () या पसंद के द्वारा वापस किया गया है, तो, नहीं, यह निर्धारित करने का कोई तरीका नहीं है कि पॉइंटर किस डेटा को इंगित करता है और इस प्रकार, इसका आकार निर्धारित करने का कोई तरीका नहीं है

 #include <stdio.h> #define NUM_DAYS 5 typedef int days_t[ NUM_DAYS ]; #define SIZEOF_DAYS ( sizeof( days_t ) ) int main() { days_t days; days_t *ptr = &days; printf( "SIZEOF_DAYS: %u\n", SIZEOF_DAYS ); printf( "sizeof(days): %u\n", sizeof(days) ); printf( "sizeof(*ptr): %u\n", sizeof(*ptr) ); printf( "sizeof(ptr): %u\n", sizeof(ptr) ); return 0; } 

आउटपुट:

 SIZEOF_DAYS: 20 sizeof(days): 20 sizeof(*ptr): 20 sizeof(ptr): 4 

जैसा कि सभी सही उत्तरों बताए गए हैं, आप अकेले ही सरणी के क्षयकर्ता सूचक मूल्य से यह जानकारी नहीं प्राप्त कर सकते हैं। यदि कष्टकारी सूचक फ़ंक्शन द्वारा प्राप्त तर्क है, तो उस आकार के बारे में पता करने के लिए फ़ंक्शन को किसी अन्य तरीके से प्रारंभिक सरणी का आकार प्रदान करना होगा।

इस प्रकार अब तक जो सुझाव दिया गया है उससे अलग एक सुझाव है, जो काम करेगा: इसके बजाय सरणी में एक पॉइंटर पास करें। यह सुझाव C ++ शैली सुझावों के समान है, सिवाय C सी टेम्पलेट या संदर्भ का समर्थन नहीं करता है:

 #define ARRAY_SZ 10 void foo (int (*arr)[ARRAY_SZ]) { printf("%u\n", (unsigned)sizeof(*arr)/sizeof(**arr)); } 

लेकिन, यह सुझाव आपकी समस्या के लिए मूर्खतापूर्ण है, क्योंकि फ़ंक्शन को परिभाषित किया जाता है कि उस एरे के आकार का बिल्कुल पता होना है (इसलिए, सरणी पर आकार का उपयोग करने के लिए बहुत कम आवश्यकता है)। यह क्या करता है, हालांकि, कुछ प्रकार की सुरक्षा प्रदान करता है यह आपको अवांछित आकार की एक सरणी में गुजरने से मना कर देगा।

 int x[20]; int y[10]; foo(&x); /* error */ foo(&y); /* ok */ 

यदि फ़ंक्शन किसी भी आकार के सरणी पर काम करने में सक्षम होना चाहिए, तो आपको फ़ंक्शन को आकार अतिरिक्त जानकारी के रूप में प्रदान करना होगा।

कोई जादू समाधान नहीं है सी एक चिंतनशील भाषा नहीं है वस्तुएं स्वचालित रूप से नहीं पता कि वे क्या हैं।

लेकिन आपके पास कई विकल्प हैं:

  1. जाहिर है, एक पैरामीटर जोड़ें
  2. एक मैक्रो में कॉल को लपेटें और स्वचालित रूप से पैरामीटर जोड़ें
  3. अधिक जटिल ऑब्जेक्ट का उपयोग करें एक संरचना परिभाषित करें जिसमें डायनामिक सरणी और सरणी के आकार शामिल हैं। फिर, संरचना का पता पास करें

इस समस्या का मेरा समाधान सरणी के बारे में एक मेटा-जानकारी के रूप में स्ट्रेट एरे में सरणी की लंबाई को बचाने के लिए है।

 #include <stdio.h> #include <stdlib.h> struct Array { int length; double *array; }; typedef struct Array Array; Array* NewArray(int length) { /* Allocate the memory for the struct Array */ Array *newArray = (Array*) malloc(sizeof(Array)); /* Insert only non-negative length's*/ newArray->length = (length > 0) ? length : 0; newArray->array = (double*) malloc(length*sizeof(double)); return newArray; } void SetArray(Array *structure,int length,double* array) { structure->length = length; structure->array = array; } void PrintArray(Array *structure) { if(structure->length > 0) { int i; printf("length: %d\n", structure->length); for (i = 0; i < structure->length; i++) printf("%g\n", structure->array[i]); } else printf("Empty Array. Length 0\n"); } int main() { int i; Array *negativeTest, *days = NewArray(5); double moreDays[] = {1,2,3,4,5,6,7,8,9,10}; for (i = 0; i < days->length; i++) days->array[i] = i+1; PrintArray(days); SetArray(days,10,moreDays); PrintArray(days); negativeTest = NewArray(-5); PrintArray(negativeTest); return 0; } 

लेकिन आपको देखभाल करने की सही लंबाई निर्धारित करने के बारे में ध्यान रखना होगा, क्योंकि इस लंबाई की जांच करने का कोई तरीका नहीं है, जैसे हमारे दोस्तों ने व्यापक रूप से समझाया।

नहीं, आप sizeof(ptr) का उपयोग करने के लिए सरणी ptr का आकार खोजने के लिए नहीं कर सकते।

हालांकि अतिरिक्त मेमोरी (सरणी के आकार से अधिक) को आवंटित करना उपयोगी होगा यदि आप लंबाई को अतिरिक्त स्थान में संग्रहीत करना चाहते हैं।

 int main() { int days[] = {1,2,3,4,5}; int *ptr = days; printf("%u\n", sizeof(days)); printf("%u\n", sizeof(ptr)); return 0; } 

दिनों का आकार [] 20 है जो तत्वों का कोई भी नहीं है * इसका डेटा प्रकार का आकार। जबकि सूचक का आकार 4 है, कोई बात नहीं, जो वह इंगित कर रहा है। क्योंकि एक सूचक दूसरे तत्व को उसके पते को संचयित करके इंगित करता है।

पॉइंटर के आकार के मूल्य को खोजना संभव नहीं है, क्योंकि कंपाइलर को यह नहीं पता है कि सूचक कितना समय है साइज़फ पॉइंटर 2 या 4 (कंपाइलर के आधार पर) होना चाहिए।

  #define array_size 10 struct { int16 size; int16 array[array_size]; int16 property1[(array_size/16)+1] int16 property2[(array_size/16)+1] } array1 = {array_size, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; #undef array_size 

सरणी_आकार आकार चर से गुजर रहा है:

 #define array_size 30 struct { int16 size; int16 array[array_size]; int16 property1[(array_size/16)+1] int16 property2[(array_size/16)+1] } array2 = {array_size}; #undef array_size 

उपयोग यह है:

 void main() { int16 size = array1.size; for (int i=0; i!=size; i++) { array1.array[i] *= 2; } } 

कुछ फ़ंक्शंस जो समस्या को हल करने में मदद कर सकते हैं, लेकिन मुझे यह उल्लेख करना होगा कि जेन लिंक्स और पॉल टॉम्ब्लिन जो कहते हैं वे सही हैं।

 #include <stdio.h> #include <stdlib.h> int main() { int truInt = 12345679; int intLength = snprintf( NULL, 0, "%d", truInt ); printf("size of truInt = %d: \n", intLength); int *ptr_truInt = &truInt; printf("size of ptr_truInt = %d: \n", (snprintf( NULL, 0, "%d", ptr_truInt[0] ) ) ); int daysInt[] = {1,2,3,4,5,6,7,8,9}; int *ptrIntDays = daysInt; printf("size of ptrDays = %d: \n\n", getIntPointerSize(ptrIntDays)); char *stringPointer1 = "123456789"; printf("size of stringPointer = %d: \n", getCharPointerSize(stringPointer)); char daysChar[] = {'1','2','3','4','5','6','7','8','9','\0'}; printf("size of daysChar = %u: \n", sizeof(daysChar)); char *ptrDaysChar = daysChar; printf("size of ptrDaysChar2 = %u: \n", getCharPointerSize(ptrDaysChar)); char daysChar2[] = "123456789"; char *ptrDaysChar2 = daysChar2; printf("size of ptrDaysChar2 = %u: \n", getCharPointerSize(ptrDaysChar2)); return 0; } int getIntPointerSize(unsigned pointer[]){ int i=-1; while(pointer[++i] != '\0'){} return i; } int getCharPointerSize(char *pointer){ int i=-1; while(pointer[++i] != '\0'){} return i; } 

हाय स्ट्रिंग्स में अंत में एक '\0' वर्ण है, इसलिए किसी स्ट्रिंग के आकार को कार्य के साथ मिल सकता है जैसे कि एक पूर्णांक सरणी के साथ समस्या उदाहरण के लिए है कि यू किसी वैल्यू का अंत मूल्य के रूप में उपयोग नहीं कर सकता है इसलिए एक संभावित समाधान सरणी को संबोधित करने के लिए और समापन मान के रूप में उपयोग करने के लिए NULL सूचक है

 /* http://stackoverflow.com/questions/492384/how-to-find-the-sizeof-a-pointer-pointing-to-an-array */ #include <stdio.h> /* the following function will produce the warning: * 'sizeof' on array function parameter 'a' will * return size of 'int *' [-Wsizeof-array-argument] */ void foo( int a[] ) { printf( "%lu\n", sizeof a ); } /* so we have to implement something else one possible * idea is to use the NULL pointer as a control value * the same way '\0' is used in strings but this way * the pointer passed to a function should address pointers * so the actual implementation of an array type will * be a pointer to pointer */ typedef char * type_t; /* line 18 */ typedef type_t ** array_t; /* * -- -- * -**-**- * -$$$$$- * -999- * -^- * - */ int main( void ) { array_t initialize( int, ... ); /* initialize an array with four values "foo", "bar", "baz", "foobar" * if one wants to use integers rather than strings than in the typedef * declaration at line 18 the char * type should be changed with int * and in the format used for printing the array values * at line 45 and 51 "%s" should be changed with "%i" */ array_t array = initialize( 4, "foo", "bar", "baz", "foobar" ); int size( array_t ); /* print array size */ printf( "size %i:\n", size( array )); void aprint( char *, array_t ); /* print array values */ aprint( "%s\n", array ); /* line 45 */ type_t getval( array_t, int ); /* print an indexed value */ int i = 2; type_t val = getval( array, i ); printf( "%i: %s\n", i, val ); /* line 51 */ void delete( array_t ); /* free some space */ delete( array ); return 0; } /* the output of the program should be: * size 4: * foo * bar * baz * foobar * 2: baz */ #include <stdarg.h> #include <stdlib.h> array_t initialize( int n, ... ) { /* here we store the array values */ type_t *v = (type_t *) malloc( sizeof( type_t ) * n ); va_list ap; va_start( ap, n ); int j; for ( j = 0; j < n; j++ ) v[j] = va_arg( ap, type_t ); va_end( ap ); /* the actual array will hold the addresses of those * values plus a NULL pointer */ array_t a = (array_t) malloc( sizeof( type_t *) * ( n + 1 )); a[n] = NULL; for ( j = 0; j < n; j++ ) a[j] = v + j; return a; } int size( array_t a ) { int n = 0; while ( *a++ != NULL ) n++; return n; } void aprint( char *fmt, array_t a ) { while ( *a != NULL ) printf( fmt, **a++ ); } type_t getval( array_t a, int i ) { return *a[i]; } void delete( array_t a ) { free( *a ); free( a ); } /* край */ 

नहीं, कारण सरणी अधूरापन से सूचक नियम में आता है। जब आप सरणी का संदर्भ देते हैं, तो यह सूचक पर एक रूपांतरित होता है लेकिन यह सरणी के बारे में जानकारी को फेंक देता है: जब आप सरणी के सामग्रियों और संग्रहीत आकार को जान सकते हैं, आप केवल एक संकेतक का पता और इसका आकार जानते हैं। समाधान ट्यूपल पॉइंटर + आकार के साथ काम करना है: सरणी को पतला बनाने और इसकी क्षमता भी संग्रहीत करता है