2013-06-04 35 views
1

一個問題,我找不到任何有關在互聯網上任何東西。我有這樣的小片在Linux發行版喘息運行的C代碼(樹莓派,但那不是相關的):免費()一個由系統消耗的緩衝()

void function(const char * command) 
{ 

    // Define commands for in between parameters 
    char commandPre[] = "echo "; 

    // Get the lengths of the strings 
    int len= strlen(command) + strlen(commandPre); 


    // Allocate the command 
    char * fullCommand = (char *) malloc(len * sizeof(char)); 

    // Build the command 
    strcat(fullCommand, commandPre); 
    strcat(fullCommand, command); 


    // Execute command 
    system(fullCommand); 

    // Free resources 
    free(fullCommand); 
} 

現在,我運行這段代碼從一個服務程序。但是當它第二次達到free(fullCommand)時(當函數在程序中第二次被調用時),程序崩潰並且存在。當我刪除免費(fullCommand)時,它按預期工作。

我的問題是:是系統()已釋放「fullCommand」給我嗎?如果是這樣,爲什麼第二次而不是第一次?我在這裏錯過了什麼嗎?

P.S.其實命令是建立strcat'ed在一起有若干字符串組成,但上述是其最基本的形式

回答

3

代碼你有一個緩衝區溢出,因爲你不是一個字符串結束分配空間。

此外,don't cast the return value of malloc(),並假設分配之前檢查返回值的工作。

另外,正如您在自己的答案中指出的,在新分配的緩衝區上使用strcat()會中斷,因爲緩衝區不會是空字符串。對不起,以前沒有選擇。

+0

啊對,愚蠢的愚蠢的愚蠢我*擊中頭*。謝謝!我一直在編程C#一段時間,我完全忘記了終結者。此外,我總是這樣做,因爲它速度很快,但檢查返回值是更好的練習,謝謝你的提示! – Maarten

+0

@Maarten「它快」?它不能更快​​(打字,我假定你的意思是)而不是*鍵入演員陣容,可以嗎?沒有性能差異,演員也沒有比檢查返回值更「糟糕」,而是完全不同的東西。演員將愉快地將一個NULL轉換爲一個字符指針,然後事情就會中斷。 – unwind

-1

我發現我的錯誤:

// Allocate the command 
    char * fullCommand = (char *) malloc(len * sizeof(char)); 

    // Build the command 
    strcat(fullCommand, commandPre); 

沒有保證fullCommand是一個malloc後空。 strcat將第二個參數的第一個字符放置在第一個參數終止符的位置。但是,終結器可能會或可能不會出現在分配數組的第一個位置,因爲malloc之後的內存中的數據是隨機的。通過做固定它:

// Allocate the command 
char * fullCommand = calloc(len, sizeof(char)); 

或者,我可以做:

// Allocate the command 
char * fullCommand = malloc(len * sizeof(char)); 
fullCommand[0] = '\0'; 

或者ALS ALK在評論中指出,啓動一個strcpy的:

// Allocate the command 
char * fullCommand = malloc(len * sizeof(char)); 

// Build the command 
strcpy(fullCommand, commandPre); 
+0

或者你可以只使用'的strcpy()',而不是爲'strcat的第一次調用()'。 – alk

+0

你的最後一個例子導致內存泄漏,因爲你用的'「」'地址覆蓋它失去()''用malloc返回的地址。你的意思是'fullCommand [0] ='\ 0''。 – alk