2010-09-07 16 views
5

मैं ग कोड का उपयोग कर फ़ाइल प्रकारों पता लगाने के लिए कोशिश कर रहा हूँ, यहाँ आदेश [], मैं उपयोग कर सकते हैं * आदेश बजाय घोषित करने के लिए यहाँ कोडग में नि: शुल्क चार सूचक

char *get_file_type(char *path, char *filename) 
{ 
    FILE *fp; 
    char command[100]; 
    char file_details[100]; 
    char *filetype; 

    sprintf(command, "file -i %s%s", path, filename); 
    fp = popen(command, "r"); 
    if (fp == NULL) { 
     printf("Failed to run command\n"); 
     exit(1); 
    } 
    while (fgets(file_details, sizeof(file_details)-1, fp) != NULL) { 
     filetype = (strtok(strstr(file_details, " "), ";")); 
    } 

    pclose(fp); 
    return filetype; 
} 

है? मैंने इसका इस्तेमाल करने की कोशिश की, लेकिन यह एक अपवाद फेंक दिया। हमें आदेश [] की तरह घोषित चर को मुक्त करने की आवश्यकता नहीं है? अगर हाँ कैसे?

उत्तर

5

आप char *command; उपयोग कर सकते हैं, लेकिन फिर, आप commandmalloc() के लिए एक कॉल के साथ उल्लेख करने के लिए और जब आप उस स्मृति ith किया जाता है, यह free() के लिए एक कॉल के साथ फिर से मुक्त हो गया है के लिए कुछ स्मृति को आबंटित करना होगा।

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

कि के अलावा, अपने कोड एक समस्या है: filetype सूचक है कि समारोह सरणी file_details के भीतर एक स्थान पर अंक देता है, लेकिन जब return बयान को क्रियान्वित कि सरणी संकलक द्वारा साफ किया जाएगा, ताकि सूचक है कि फ़ंक्शन द्वारा लौटाया जाता है कुछ स्मृति को संदर्भित करता है जिसे "अन्य उद्देश्यों के लिए उपयोग करने के लिए स्वतंत्र" के रूप में चिह्नित किया जाता है।

यदि यह एक समस्या यह है कि get_file_type का परिणाम एक समय में एक फ़ाइल के लिए मान्य है नहीं है, आप file_details सरणी static के रूप में, घोषणा कर सकते हैं इतना है कि यह कार्य करने के लिए कॉल भर में संरक्षित किया जाएगा।

+0

क्या मैं इसके बजाय strdup का उपयोग कर सकता हूं? –

+0

आप कर सकते हैं, लेकिन फिर आपको स्मृति रिसाव से बचने के लिए कॉलिंग फ़ंक्शन में 'फ्री' को कॉल करना याद रखना चाहिए। –

1

आप इसे क्यों बदलेंगे? अस्थायी बफर के लिए, लोग आम तौर पर [] के साथ सरणी घोषित करते हैं ताकि उन्हें कचरा निपटान के बारे में चिंता न करें।

+0

लेकिन क्या आप मुझे बता सकते हैं कि यह कैसे करें? –

+0

एक बात के लिए, शायद यह बफर ओवरफ्लो को चुपचाप अनुमति देने के बजाय गतिशील रूप से 'पथ' और 'फ़ाइल नाम' की लंबाई के आधार पर एक बफर आवंटित करने का अर्थ होगा। (सी 99 परिवर्तनीय लंबाई सरणी इसे हल करेंगे, हालांकि। 'Sprintf' के बजाय' snprintf' का उपयोग करने के लिए भी सलाह दी जाएगी।) – jamesdlin

+4

यह एक टिप्पणी होनी चाहिए ... – zeboidlund

11

जब आप एक सरणी की घोषणा:

char command[100]; 

संकलक इसके लिए स्मृति (इस मामले में 100 वर्ण) और कहा कि स्मृति के शुरू करने के command अंक आवंटित करता है। आप स्मृति आप आवंटित है उनका उपयोग कर सकते हैं:

command[0] = 'a'; // OK 
command[99] = 'A'; // OK 
command[100] = 'Z'; // Error: out of bounds 

लेकिन आप command का मूल्य बदल नहीं सकते हैं:

command = NULL;  // Compile-time error 

जब command दायरे से बाहर चला जाता है स्मृति स्वचालित रूप से मुक्त हो जाएगा।


जब आप एक सूचक की घोषणा:

char *commandptr; 

आप केवल char रों की ओर इशारा करते के लिए एक एकल चर बना है, लेकिन यह कुछ भी करने के लिए अभी तक बात नहीं करता है।जब आप इसके साथ समाप्त किया है

commandptr = malloc(100); 
if (commandptr) { 
    // Always check that the return value of malloc() is not NULL 
    commandptr[0] = 'A'; // Now you can use the allocated memory 
} 

और यह मुफ़्त:

commandptr[0] = 'A'; // Undefined behaviour; probably a segfault 

आप स्मृति अपने आप को आवंटित करने के लिए malloc का उपयोग कर की जरूरत है: यह initialising बिना इसका इस्तेमाल करने के प्रयास में कोई त्रुटि है

free(commandptr); 
+0

असल में, स्टैक सरणी मुक्त नहीं होती है, क्योंकि इसकी आवश्यकता नहीं होती है। पूरी तरह से ईमानदार होने के लिए, malloc और free syscalls (अच्छी तरह से, उन्हें रैपर) हैं, जबकि ढेर सरणी नहीं हैं। – KAction

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