2012-04-12 19 views
22

मैं सी कोड लिख रहा हूं और मैं 512 * 256 बाइट आवंटित करना चाहता हूं। अपनी खुद की सुविधा के लिए मैं सिंटैक्स सरणी [ए] [बी] के साथ तत्वों तक पहुंचने में सक्षम होना चाहता हूं; सही सूचकांक खोजने के लिए कोई अंकगणित नहीं है।ढेर एक 2 डी सरणी आवंटित करें (पॉइंटर्स की सरणी नहीं)

मैं देखता हूं कि हर ट्यूटोरियल मुझे पॉइंटर्स की एक सरणी बनाने के लिए कहता है जो मेरी सरणी में पंक्तियों के सरणी को इंगित करता है। इसका मतलब है कि प्रत्येक उपन्यास को malloc'd और व्यक्तिगत रूप से मुक्त किया जाना चाहिए। मुझे ऐसे समाधान में दिलचस्पी है जिसमें केवल एक कॉल को मॉलोक और एक कॉल फ्री करने की आवश्यकता है। (इस प्रकार सभी तत्व संगत हैं) मुझे लगता है कि यह संभव है क्योंकि मैं एक जंजीर सरणी नहीं बनाऊंगा।

अगर कोई ऐसी सरणी घोषित करने के लिए सिंटैक्स साझा कर सकता है तो मैं सराहना करता हूं।

+1

क्या सी ++ एक विकल्प है? आप एक साधारण सी ++ ऑब्जेक्ट्स बना सकते हैं जो इंडेक्सिंग ऑपरेटर को ओवरलोड करता है। –

+4

@ रिचर्ड जे। रौसीआईआई: क्या यह सचमुच एक प्रश्न है कि "मैं सी में यह कैसे कर सकता हूं?" (यह महसूस कर रहा है कि आपने * टिप्पणी के रूप में इसे छोड़ दिया है)। मैं किसी भी दिन धन्यवाद सी ++ सी ले जाएगा। –

+0

@ एडीएस। जबकि आप सी को पसंद कर सकते हैं, सी ++ कुछ स्थितियों में बेहतर है, और यह उनमें से एक होगा। मैंने यह निर्धारित करने के लिए बस एक टिप्पणी के रूप में छोड़ा कि यह एक विकल्प होगा या नहीं। –

उत्तर

34

ठीक है, अगर आप प्रकार की सरणी आवंटित करना चाहते हैं, तो आप इसे उस प्रकार के सूचक में असाइन करें।

के बाद से 2 डी सरणियों सरणियों के सरणियों हैं (आपके मामले में, 256 वर्ण के 512 सरणियों की एक सरणी), तो आप इसे 256 वर्ण की सरणी के लिए सूचक में आवंटित करने चाहिए:

char (*arr)[256]=malloc(512*256); 
//Now, you can, for example: 
arr[500][200]=75; 

(कोष्ठकों के आसपास *arr इसे सरणी के लिए एक सूचक बनाने के लिए, और पॉइंटर्स की एक श्रृंखला नहीं है)

+0

+1, किसी भी तरह से मुझे याद आया कि जब आप मेरा जवाब लिख रहे थे तो आपने इसे पोस्ट किया था। :-) –

+0

यह वही है जो मैं ढूंढ रहा था। धन्यवाद। – Paul

+3

ध्यान दें कि सी 99 के बाद आयामों को संकलन समय में अब जाना नहीं है। आप 'n, m' stdin से पढ़ सकते हैं और 'char arr [n] [m]' या, इस मामले में,' char (* arr) [n] 'घोषित कर सकते हैं। – Kos

14

यदि आप इस तरह की सरणी आवंटित करते हैं, तो उसे free पर दो कॉल की आवश्यकता होती है, लेकिन यह array[a][b] शैली वाक्यविन्यास की अनुमति देता है और यह संगत है।

char **array = malloc(512 * sizeof(char *)); 
array[0] = malloc(512*256); 
for (int i = 1; i < 512; i++) 
    array[i] = array[0] + (256 * i); 

अधिक जानकारी के लिए यहां array2 देखें: http://c-faq.com/aryptr/dynmuldimary.html

+0

यह एक अच्छी चाल है! +1 –

+3

आप डोप वेक्टर के तुरंत बाद डेटा ब्लॉक डालकर दो आवंटन को जोड़ सकते हैं। एक निश्चित मात्रा में fiddly टाइपकास्टिंग की आवश्यकता है लेकिन यह मुश्किल नहीं है। हालांकि, दिखाए गए आपके कोड में एक गंभीर बग है: आप 512 'char के लिए स्थान आवंटित करते हैं, और फिर आप 512' char * के लिए पर्याप्त स्थान के रूप में इसका इलाज करते हैं। यह आवंटन और दुर्घटना के अंत से बाहर निकलने की गारंटी के बारे में है। – zwol

+0

ओप्स टाइपो, इसे करना चाहिए ... –

5

जब से तुम समय से आगे सरणी के आकार पता है, तुम एक struct प्रकार है कि एक 521x256 सरणी शामिल बना सकते हैं, और फिर गतिशील struct आवंटित।

2

यदि आप सरणी के आकार को जानते हैं, तो आप typedef इसे कर सकते हैं, और इसे पॉइंटर बना सकते हैं। यहाँ एक छोटा स्निपेट है कि इस प्रयोग को दर्शाता है है:

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

typedef int array2d[20][20]; 

int main() { 
    int i,j; 
    array2d *a = malloc(sizeof(array2d)); 
    for(i=0;i!=20;i++) 
     for(j=0;j!=20;j++) 
      (*a)[i][j] = i + j; 

    for(i=0;i!=20;i++) 
     for(j=0;j!=20;j++) 
      printf("%d ",(*a)[i][j]); 
    free(a); 
    return 0; 
} 
+0

दिलचस्प समाधान, क्या कोई तरीका है कि आप यह समझ सकते हैं कि गतिशील सरणी के साथ ऐसा कैसे करें? –

+0

@ रिचर्ड जे। रॉसआईआई दुर्भाग्यवश, यह गतिशील रूप से आकार वाले सरणी के साथ काम नहीं करता है, क्योंकि टाइपपीफ को दोनों आयामों के लिए संकलन-समय स्थिरांक की आवश्यकता होती है। सबसे अच्छा आप कर सकते हैं एक आयाम तय करने के लिए और अन्य गतिशील, लेकिन यह इसे पूरी तरह से गतिशील नहीं बना देगा। – dasblinkenlight

+0

टाइपपीफ अनावश्यक है और वास्तव में टाइपिफ़ में दोनों आयामों को रखना हानिकारक है क्योंकि आप केवल 'plain' के बजाय जगह पर '(* ए)' का उपयोग करके फंस गए हैं। यदि आप केवल कॉलम की संख्या डालते हैं, तो यह बहुत बेहतर काम करेगा। और निश्चित रूप से सी 99 के साथ, आप प्रकार को विविधता से संशोधित कर सकते हैं; मेरा मानना ​​है कि यह टाइपिफ़ में तब भी मान्य है जब तक टाइपिफ़ के पास फ़ाइल स्कोप के बजाय ब्लॉक स्कोप होता है। –

2

यह गतिशील बहुआयामी सरणी कि

static char x[512][256]; 

आप देता है उसी तरह का आवंटन करने के लिए संभव है, लेकिन यह प्रकार की वजह से एक सुबह मुश्किल है क्षय। मैं केवल जानते हैं कि कैसे एक typedef साथ यह करने के लिए:

typedef char row[512]; 
row *x = malloc(sizeof(row) * 256); 

यह केवल आप रनटाइम पर दूसरे आयाम का आकार निर्धारित करने देता है। यदि दोनों आयाम रनटाइम पर भिन्न हो सकते हैं, तो आपको एक डोप वेक्टर की आवश्यकता होती है।

+0

इसे भी याद किया। ध्यान दें कि जब तक आप C89 तक सीमित न हों, दोनों आयाम भिन्न हो सकते हैं; आपको बस एक भिन्न-संशोधित सूचक प्रकार का उपयोग करने की आवश्यकता है। –

11

यह आसान है कि आपको प्राचीन सी 8 9 मानक (वर्तमान सी कंपाइलर्स, केवल एमएसवीसी और कुछ एम्बेडेड-लक्षित के बीच संगतता की आवश्यकता नहीं है) कंपाइलर्स पीछे की तरफ हैं)। यहाँ कैसे आप यह कर दिया गया है:

int (*array)[cols] = malloc(rows * sizeof *array); 

फिर array[a][b][0,rows) में किसी भी a और [0,cols) में b लिए मान्य है।

सी मानक की भाषा में, array में विविधता से संशोधित प्रकार है। यदि आप पॉइंटर को अन्य कार्यों में पास करना चाहते हैं, तो आपको फ़ंक्शन तर्क सूची में इस प्रकार को दोहराना होगा और सुनिश्चित करें कि कम से कम कॉलम की संख्या फ़ंक्शन पर पास की जाती है (क्योंकि इसे भिन्न रूप से संशोधित के हिस्से के रूप में आवश्यक है प्रकार)।

संपादित करें: मुझे इस तथ्य को याद आया कि ओपी केवल एक निश्चित आकार, 512x256 की परवाह करता है। उस मामले में, C89 पर्याप्त होगा, और आप सभी की जरूरत है:

int (*array)[256] = malloc(512 * sizeof *array); 

ठीक उसी प्रकार समारोह तर्क सूचियों में इस्तेमाल किया जा सकता है अगर आप कार्यों के बीच चारों ओर सूचक पास करनी होगी (और यह भी एक समारोह वापसी प्रकार के रूप में , लेकिन इस उपयोग के लिए आप इसे टाइप करना चाहते हैं ... :-)

+0

आप सामान्य मामले में सही हैं, लेकिन ओपी केवल 512 * 256 सरणी चाहता है। – asaelr

+0

दरअसल, तो मैं जवाब अपडेट कर दूंगा। –

+0

वास्तव में, यह उत्तर उत्कृष्ट है। हालांकि मुझे केवल 512 * 256 की आवश्यकता है, लेकिन मैं भविष्य में इस आवश्यकता को आसानी से बदल सकता हूं। – Paul