2010-04-28 14 views
8

जीसीसी 4.4.1 C89का उपयोग sizeof

मैं निम्नलिखित कोड का टुकड़ा है:

#include <stdlib.h> 
#include <stdio.h> 

char *buffer = malloc(10240); 
/* Check for memory error */ 
if(!buffer) 
{ 
    fprintf(stderr, "Memory error\n"); 
    return 1; 
} 
printf("sizeof(buffer) [ %d ]\n", sizeof(buffer)); 

हालांकि, sizeof (बफर) हमेशा प्रिंट 4. मैं एक चार जानते हैं कि * केवल 4 बाइट है। हालांकि, मैंने 10kb के लिए स्मृति आवंटित की है। तो आकार 10240 नहीं होना चाहिए? मुझे आश्चर्य है कि क्या मैं यहाँ सोच रहा हूँ?

किसी भी सुझाव के लिए बहुत धन्यवाद,

+2

अधिकांश भाग के लिए सी कंपाइलर (किसी भी संस्करण के लिए) को कोई विचार नहीं है कि फ़ंक्शन 'malloc' वास्तव में क्या करता है या इसका उपयोग किया जाता है। यह सब जानता है कि यह एक हस्ताक्षरित पूर्णांक (size_t) लेता है और एक शून्य सूचक देता है। यह यादृच्छिक संख्या जेनरेटर के बीज के लिए इसका पैरामीटर का उपयोग कर सकता है और सभी कंपाइलर परवाह के लिए एक यादृच्छिक संख्या को '(शून्य *)' में डाल सकता है, इसलिए संकलक यह नहीं जान सकता कि स्मृति का आकार क्या है। – nategoose

उत्तर

14

आप char* के आकार के लिए पूछ रहे हैं जो वास्तव में 4 है, बफर का आकार नहीं है। sizeof ऑपरेटर एक गतिशील आवंटित बफर के आकार को वापस नहीं कर सकता, केवल स्थिर प्रकारों और संकलित समय पर ज्ञात structs का आकार।

+2

'sizeof' सी 99 में परिवर्तनीय लंबाई सरणी के लिए एक गतिशील बफर के आकार को वापस कर सकता है। –

+0

क्या सी 8 9 के तहत कोई तरीका है कि आप गतिशील आवंटित बफर के साथ कितनी मेमोरी आवंटित की गई है? धन्यवाद। – ant2009

+2

@ करल - वीएलए गतिशील नहीं हैं। वे "परिवर्तनीय लंबाई" हैं कि उनकी लंबाई को रनटाइम पर गणना की जा सकती है, लेकिन "चर लंबाई" नहीं है कि उनकी लंबाई बदल सकती है। वे अभी भी स्टैक-आधारित सरणी हैं, यही कारण है कि 'sizeof' को उनके लिए काम करने के लिए परिभाषित किया गया है। –

9

sizeof गतिशील आवंटन पर (C99 में कुछ अपवादों को छोड़कर) काम नहीं करता। sizeof का आपका उपयोग सिर्फ आपको सूचक का आकार दे रहा है। इस कोड को आप परिणाम आप चाहते हैं दे देंगे:

char buffer[10240]; 
printf("sizeof(buffer) [ %d ]\n", sizeof(buffer)); 

तो malloc() सफल होता है, स्मृति बताया करने के लिए कम से कम के रूप में बड़ा है के रूप में आप के लिए कहा है, इसलिए वहां वास्तविक आकार यह आवंटित के बारे में देखभाल करने के लिए कोई कारण नहीं है।

इसके अलावा, आपने 10 केबी आवंटित किए हैं, 1 केबी नहीं।

+0

यह कोड थोड़ा खतरनाक से अधिक है: यह ढेर पर बफर आवंटित नहीं कर रहा है, ढेर नहीं। यदि आप इस बफर को किसी भी पॉइंटर्स से बाहर निकलने वाले फ़ंक्शन से बाहर निकलने देते हैं, तो आप भ्रष्टाचार को रोकने के रास्ते पर हैं (और यह निर्भर करता है कि आपका कार्यक्रम कितना समय चलता है, भ्रष्टाचार और/या विभाजन खंड को ढेर करता है)। – Anon

+2

@Anon - यह खतरनाक नहीं है, यह समस्या को एक अलग तरीके से हल करता है। एक समारोह से बफर को वापस पास करने के बारे में ओपी की कोई आवश्यकता नहीं थी। –

+0

और ओपी की समस्या क्या है?मुझे लगता है कि यह ढेर-आवंटित संरचना के आकार का ट्रैक रख रहा है। यह सुझाव देते हुए कि ओपी एक स्टैक-आवंटित संरचना का उपयोग उस समस्या का समाधान नहीं है। – Anon

3

यदि आपको इसकी आवश्यकता है तो स्मृति के आकार को ट्रैक करने के लिए आप पर निर्भर है। मॉलोक द्वारा लौटाई गई स्मृति केवल "अनियमित" डेटा के लिए एक सूचक है। आकार का ऑपरेटर केवल buffer चर पर काम कर रहा है।

+0

निश्चित रूप से रनटाइम पर्यावरण आवंटित बफर के आकार को जानता है (क्योंकि 'मुक्त (शून्य *)' आकार के लिए नहीं पूछता है), तो हमें इसे अपने बारे में क्यों ट्रैक रखना चाहिए? – Dai

+0

अंतर्निहित स्मृति प्रबंधन कोड लगभग निश्चित रूप से आकार का है जब तक कि इसमें कुछ जादुई एल्गोरिदम मुक्त नहीं होता है जिसके लिए आकार की आवश्यकता नहीं होती है। लेकिन वह जानकारी प्रकट नहीं हुई है। –

+0

क्या कोई कारण है कि डेटा का खुलासा नहीं किया गया है? – Dai

2

malloc_usable_size द्वारा बदलें (मैनपेज इंगित करता है कि यह गैर-पोर्टेबल है, इसलिए आपके विशेष सी कार्यान्वयन के साथ उपलब्ध नहीं हो सकता है)।

+1

'malloc_usable_size()' बहुत गैर पोर्टेबल है। मेरे पास ओएस एक्स तेंदुए पर नहीं है। वैसे भी, इस पर निर्भरता पहली जगह में एक भयानक विचार है (जैसा कि मैनपेज में भी कहा गया है)। –

+0

नोट: यदि आपको पोर्टेबिलिटी की परवाह नहीं है और ओएसएक्स पर है (या किसी और ने परवाह नहीं की है और आप ओएसएक्स को पोर्टिंग के साथ फंस गए हैं) malloc_size से आपका काम नौकरी के लिए है। – Stripes

3

सं। bufferchar * है। यह char डेटा के लिए एक सूचक है। सूचक केवल 4 बाइट्स (आपके सिस्टम पर) लेता है।

यह 10240 बाइट डेटा (जो, वैसे, 1 केबी नहीं है। 10Kb की तरह), लेकिन सूचक को पता नहीं है। विचार करें:

int a1[3] = {0, 1, 2}; 
int a2[5] = {0, 1, 2, 3, 4}; 

int *p = a1; 
// sizeof a1 == 12 (3 * sizeof(int)) 
// but sizeof p == 4 
p = a2 
// sizeof a2 == 20 
// sizeof p still == 4 

यह सरणी और पॉइंटर्स के बीच मुख्य अंतर है। अगर यह इस तरह से काम नहीं करता है, तो sizeof p उपरोक्त कोड में बदल जाएगा, जो एक संकलन-समय निरंतर के लिए समझ में नहीं आता है।

संबंधित मुद्दे