2010-08-19 15 views
10

सी में, मैं इसे एक फ़ंक्शन पर भेजकर पॉइंटर का मान सेट करने का प्रयास कर रहा हूं, लेकिन मान फ़ंक्शन के बाहर नहीं बदलता है।फ़ंक्शन के माध्यम से पॉइंटर संदर्भ कैसे सेट करें

#include <stdio.h> 
void foo(char* str) { 

    char* new_str = malloc(100); 
    memset(new_str, 0, 100); 
    strcpy(new_str, (char*)"new test"); 

    str = new_str; 
} 


int main (int argc, char *argv[]) { 

    char* str = malloc(100); 
    memset(str, 0, 100); 

    strcpy(str, (char*)"test"); 

    foo(str); 

    printf("str = %s\n", str); 
} 

मैं बाहर प्रिंट करना चाहते हैं:

str = new test 

लेकिन इस कोड को प्रिंट आउट:

str = test 

किसी भी मदद की सराहना की होगी यहाँ मेरी कोड है। अग्रिम में धन्यवाद।

उत्तर

17

सी में कोई पास-बाय-रेफरेंस नहीं है। यदि आप str को सी में किसी फ़ंक्शन के तर्क के रूप में प्रदान करते हैं, तो आप हमेशा str के वर्तमान मान को पास कर रहे हैं, कभी भी str कभी नहीं।

आप समारोह में str के लिए एक सूचक गुजारें सकता:

void foo(char** pstr) { 
    // ... 
    *pstr = new_str; 
} 

int main() { 
    // ... 
    foo(&str); 
} 

Eiko कहते हैं, अपने उदाहरण कोड पहले स्मृति आवंटन लीक। अब आप इसका उपयोग नहीं कर रहे हैं, और अब आपके पास कोई सूचक नहीं है, इसलिए आप इसे मुक्त नहीं कर सकते हैं। ये गलत है।

+0

"कोई पास-संदर्भ द्वारा सी में" - नहीं सरणियों संदर्भ द्वारा पारित कर दिया है? – naivnomore

+0

@naivnomore मूल रूप से आप एक सूचक को पास करते हैं जो (कम से कम वाक्य रचनात्मक रूप से) C++ में संदर्भ पारित करने के लिए अलग होता है। – Eiko

+1

नहीं, वे नहीं हैं। पैरामीटर के रूप में पारित होने पर पॉइंटर्स को Arrays क्षय, लेकिन यह अभी भी पास-दर-संदर्भ नहीं है क्योंकि सूचक तर्क के मान को बदलना सरणी को प्रभावित नहीं करेगा। –

3

आप सूचक को सूचक उपयोग करने की आवश्यकता अपरीक्षित:

#include <stdio.h> 

void foo(char** str) 
{ 
    char* new_str = malloc(100); 
    memset(new_str, 0, 100); 
    strcpy(new_str, (char*)"new test"); 
    if (str) { /* if pointer to pointer is valid then */ 
     if (*str) /* if there is a previous string, free it */ 
      free(*str); 
     *str = new_str; /* return the string */ 
    } 
} 


int main (int argc, char *argv[]) 
{ 
    char* str = malloc(100); 
    memset(str, 0, 100); 

    strcpy(str, (char*)"test"); 

    foo(&str); 

    printf("str = %s\n", str); 
} 
+0

शायद आप 'if (str)' के बजाय 'if (str)' का अर्थ है। यद्यपि उस परिवर्तन के साथ भी, जहां 'str' शून्य है,' foo' आवंटन को रिसाव करता है। –

+0

@ स्टेव: ओह। धन्यवाद। ठीक कर दिया। – Dummy00001

+0

इसके अलावा: 'मुक्त (0)' कुछ भी नहीं करता है। लेकिन 'फ्री' कॉल करने से पहले शून्य के लिए जांचना वास्तव में गलत नहीं है। –

2

तुम सिर्फ एक सूचक है, जो foo में एक स्थानीय चर रहा है फिर नियत कर रहे हैं।

आप स्ट्रिंग की प्रतिलिपि बनाना चाहते हैं, तो का उपयोग strcpy(str, new_str);

आप सूचक के लिए एक संदर्भ के बजाय गुजर सकता है और पुन: असाइन, लेकिन यह आसानी से मेमोरी लीक करने के लिए नेतृत्व कर सकते हैं और बनाए रखने के लिए कठिन है।

संपादित करें: संदर्भ के अनुसार छद्म पास के लिए स्टीव द्वारा उत्तर देखें।

1

मैंने इस तरह से फ़ंक्शन से पॉइंटर लौटकर ऐसा किया। इस मामले में मॉलोक का उपयोग करने का कोई कारण नहीं है, इसलिए आपको मुफ्त में चिंता करने की ज़रूरत नहीं है।

जीसीसी 4.4.3 C89

char* print_test(char *str) 
{ 
    char *new_str = "new_test"; 
    printf("new_str [ %s ]\n", new_str); 
    str = new_str; 
    return str; 
} 

int main(void) 
{ 
    char *str = "test"; 

    printf("str [ %s ]\n", str); 

    str = print_test(str); 

    printf("str [ %s ]\n", str); 

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