2017-03-12 51 views
-3

我有以下代碼,當試圖訪問數組splitted時,會給我Segfault。我是否以錯誤的方式重新分配指針數組?重新分配指向字符的指針數組

void allocate (char** splitted) { 
    splitted = malloc(sizeof(char*)); 
    for (int i = 0; i < 3; i++) { 
     splitted = realloc(splitted, (i + 1) * sizeof(char*)); 
     splitted[i] = "asd"; 
    } 
} 

int main() { 
    char** splitted = NULL; 
    allocate(splitted); 
    for (int i = 0; i < 3; i++) { 
     printf("%s", splitted[i]); 
    } 
    return 1; 
} 
+0

試圖在這樣的循環中擴展'splitted'而不是在循環之前嘗試'malloc'所需的大小的動機是什麼? –

+0

使用'allocate'的結果,當前'void'返回新的序列地址。 – WhozCraig

+0

你沒有包含任何庫頭文件,請不要因爲你有代表而認爲「我們知道你做了」。你應該更清楚。 –

回答

2

是的,你是以錯誤的方式重新分配你的數組 - 實際上是一些錯誤的方法。

你忘了splitted通過到函數。因此,對函數內部值的任何更改對調用者都是不可見的。

因此,要麼改變函數添加一個額外的間接級別。

void allocate (char*** splitted) 
{ 
    *splitted = malloc(sizeof(char*)); 
    for (int i = 0; i < 3; i++) 
    { 
     *splitted = realloc(splitted, (i + 1) * sizeof(char*)); 
     (*splitted)[i] = "asd"; 
    } 
} 

/* to call it in main() */ 

allocate(&splitted); 

或將其更改爲返回新值

char *allocate (char** splitted) 
{ 
    splitted = malloc(sizeof(char*)); 
    for (int i = 0; i < 3; i++) 
    { 
     splitted = realloc(splitted, (i + 1) * sizeof(char*)); 
     splitted[i] = "asd"; 
    } 
    return splitted; 
} 

/* to call it in main() */ 

splitted = allocate(splitted); 

其他一些注意事項如下。

我假設你在你的代碼之前有一個#include <stdlib.h>(否則使用malloc()realloc()將不能編譯)。將來,提供一個MCVE,所以試圖幫助你的人不必對你遺漏的東西做出假設或猜測。

該函數中的malloc()的調用是不需要的,因爲realloc()可以接受NULL

此外,realloc()不需要在循環中。循環之前將會有一個realloc() - 只提供最終的預期大小。

強烈建議檢查功能的返回值,如realloc()malloc(),因爲它們都可以返回錯誤指示。顯然,如果你檢查返回值,你也需要明智地處理錯誤。

由於您的代碼使用malloc()/realloc()來分配內存,因此您還需要釋放它。例如在main()的末尾free(splitted)。是的,現代操作系統清理 - 除非不是所有的系統都這麼做 - 所以不使用free()是一個不好的習慣。此外,如果您重複使用代碼(例如,將您的main()重命名爲其他函數,並從其他函數中調用它),您將會遇到內存泄漏。