2010-09-07 106 views
5

我試圖找出使用C代碼的文件類型,這裏是代碼免費字符指針

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;,但是,你必須分配一些內存command與呼叫是指以malloc(),當你第i個內存完成的,它必須與以free()呼叫再次釋放。如你所見,與使用固定大小的數組相比,這要做得更多(如你現在所做的那樣),但它也可以變得更安全,因爲你可以創建一個完全正確的緩衝區大小,而不是希望命令的總長度不會超過100個字符。

除此之外,你的代碼有一個問題:filetype指針,該函數返回指向數組file_details內的位置,但陣列將由編譯器執行return報表時予以清理,所以指針被函數返回是指一些被標記爲「可以用於其他目的」的內存。

如果get_file_type的結果一次只對一個文件有效,那麼可以將file_details數組聲明爲static,以便在調用該函數時保留該數組。

+0

我可以使用strdup嗎? – 2010-09-07 09:22:03

+0

你可以,但是你必須記得在調用函數中調用'free'來避免內存泄漏。 – 2010-09-07 09:52:42

1

你爲什麼要改變它?對於臨時緩衝區,人們通常用[]聲明數組,以便他們不必擔心垃圾處理。

+0

但你能解釋我該怎麼做嗎? – 2010-09-07 08:33:22

+0

首先,根據'path'和'filename'的長度動態分配一個緩衝區,而不是默默地允許緩衝區溢出可能是有意義的。 (但是C99可變長度數組可以解決這個問題,使用'snprintf'而不是'sprintf'也是可取的。) – jamesdlin 2010-09-07 09:54:28

+4

這應該是一條評論... – zeboidlund 2012-12-01 07:05:14

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 S,但它不指向任何東西。嘗試使用沒有初始化它是一個錯誤:

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

你需要使用malloc自己分配內存:

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 
} 

,並釋放它當你完成它:

free(commandptr); 
+0

實際上,堆棧數組不會被釋放,因爲它不需要。 說實話,malloc和free是系統調用(好吧,它們的包裝),而堆棧數組不是。 – KAction 2012-07-07 03:19:43