2011-03-21 21 views
9

मैं एक नई पूर्णांक सरणी बनाने की कोशिश कर रहा हूं जो वर्णों की एक स्ट्रिंग से ली गई है। उदाहरण के लिए:फ़ंक्शन से लौटने वाली Arrays/पॉइंटर्स

char x[] = "12334 23845 32084"; 

int y[] = { 12334, 23845, 32084 }; 

मैं कैसे समझ एक समारोह से एक सरणी (जो मुझे समझ में संभव नहीं है) वापस जाने के लिए परेशानी हो रही हूँ।

मैं मूल रूप से करने की कोशिश की:

/* Convert string of integers into int array. */ 
int * splitString(char string[], int n) 
{ 
    int newArray[n]; 

    // CODE 

    return (newArray); 
} 

int main(void) 
{ 
    int x[n] = splitString(string, n); 

    return (0); 
} 

मैं बाद में पता चला कि यदि आप ऐसा नहीं कर सकते हैं।

पॉइंटर्स फ़ंक्शंस के संबंध में कैसे काम करते हैं?

धन्यवाद।

उत्तर

15

आमतौर पर, आपको कॉलर को परिणाम सरणी में पास करने की आवश्यकता होती है।

void splitString(const char string[], int result[], int n) { 
    //.... 
} 

यह फायदेमंद है क्योंकि कॉलर जहां भी चाहें उस स्मृति को आवंटित कर सकता है।

+0

यह पसंदीदा तरीका है। 99% मामलों में किसी फ़ंक्शन से किसी भी प्रकार के पॉइंटर को वापस करने का अर्थ नहीं होता है। – Lundin

+5

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

+0

@JCooper: कॉलर उस मेमोरी को पूल से, स्टैक से बाहर या कहीं भी उसे कहीं भी रखना चाहता है, लेकिन फ़ंक्शन नहीं कर सकता है। – Puppy

5
int * splitString(char string[], int n) 
{ 
    int newArray[n]; 
    return (newArray); 
} 

यह बहुत बुरा है! फ़ंक्शन लौटने पर सरणी newArray फ़ंक्शन के लिए स्थानीय नष्ट हो जाती है। आपको एक खतरनाक सूचक के साथ छोड़ दिया जाएगा और इसका उपयोग करके अपरिभाषित व्यवहार का आह्वान होगा।

आप किसी फ़ंक्शन से सरणी वापस नहीं कर सकते हैं। सबसे अच्छा आप कर सकते हैं

int * splitString(char string[], int n) 
{ 
    int *newArray = malloc(n*sizeof(int)); // the array gets allocated on the heap rather than on the stack(1) 
    // Code 
    return (newArray); 
} 

आवंटित स्मृति को मुक्त करने के लिए मत भूलना।

(1) ध्यान दें कि मानक स्टैक या ढेर शब्द का उपयोग/परिभाषित नहीं करता है।

+0

हाँ मैं अब कि एहसास जाना होगा। मैंने कुछ उदाहरणों के लिए वेब को सही तरीके से कार्यान्वित करने के तरीके पर खराब कर दिया है, हालांकि मुझे कुछ भी नहीं मिला है। – Garee

+0

@prasoonSaurav, तो आपने उल्लेख किया है, फ़ंक्शन में नया ऐरे स्थानीय नष्ट हो जाता है ताकि हम पॉइंटर वापस कर सकें। सूचक आमतौर पर स्मृति के पते को संग्रहीत करता है, फिर यदि हम उस सूचक को वापस लौटाते हैं जिसमें फ़ंक्शन के भीतर बनाई गई स्मृति का पता होता है, तो वह स्मृति भी नष्ट हो जाएगी? क्या आप कृपया मुझे समझा सकते हैं, मुझे जवाब नहीं मिला –

+0

ठीक है मुझे यहां जवाब मिला है https://stackoverflow.com/a/11656585/4146319 –

12

समस्या यह है कि आप स्टैक पर किसी चीज़ को पॉइंटर लौट रहे हैं। फिर आप यह मुक्त कर काम पूरा हो जाने, ढेर पर अपने सरणी बनाने की जरूरत:

int * splitString(char string[], int n) 
{ 
    int *newArray = malloc(sizeof(int) * n); 

    // CODE 

    return (newArray); 
} 

int main(void) 
{ 
    int *x = splitString(string, n); 

    // use it 

    free(x); 

    return (0); 
} 
3

बल्कि return (newArray) साथ एक सरणी लौटने से, आप एक सूचक newArray के पहले तत्व पर वापस जाएँ।

समस्या यह है कि आप सरणी को गलत तरीके से आवंटित कर रहे हैं। यदि आप int newArray[n] के साथ इसे तुरंत चालू करते हैं, तो वर्तमान स्टैक फ्रेम पर स्मृति आवंटित की जाती है। जैसे ही आपका फ़ंक्शन वापस आ जाएगा, वह स्मृति मुक्त हो जाएगी, और सरणी में जो कुछ भी था, वह कचरा होगा।

int *newArray = malloc(n * sizeof(int)); 
// etc. 
return newArray 

malloc का उपयोग करके आप ढेर, जहां यह वर्तमान ढेर फ्रेम के अंत अतीत बच जाएगा पर स्मृति को आबंटित: इसके बजाय, निम्न कार्य करें। जब आप पूरा कर लें तो बस अपने कार्यक्रम में free(newArray) को याद रखें।

1

बेशक यह संभव है। int func(int** results)

समारोह results में तत्वों की संख्या देता है: इस तरह से मैं पसंद करते है। results एक int सरणी के लिए एक सूचक है।

2

आप एक संरचना में एक सरणी लपेट सकते हैं और फिर संरचना का एक उदाहरण वापस कर सकते हैं। मैं पूर्णता के लिए इसका जिक्र कर रहा हूं, यह वास्तव में ऐसा कुछ नहीं है जिसे आप करना चाहते हैं क्योंकि यह बदसूरत है और बेहतर विकल्प हैं।

#include <stdio.h> 

struct retval 
{ 
    int a[10]; 
}; 

struct retval test() 
{ 
    struct retval v = {{1, 5, 6}}; 
    return v; 
} 

int main() 
{ 
    struct retval data = test(); 
    printf("%d %d\n", data.a[1], data.a[2]); 
} 
+0

बस सोच रहा है, यह कैसे काम करता है? "परीक्षण" के ढेर पर किसी स्थान पर "v.a" सूचक नहीं है? "संरचना retval डेटा = परीक्षण();" परिणामस्वरूप सरणी की गहरी प्रतिलिपि है? – Pradyumna

2

मैं इसके बारे में इस तरह से

/* Convert string of integers into int array. */ 
void splitString(char string[], int *out_arr, int n) 
{ 

    // code that fills each cell of out_arr 

} 

int main(void) 
{ 
    int x[n]; 
    splitString(string,(int *)x, n); 

    return (0); 
} 
संबंधित मुद्दे