2016-04-28 99 views
0

我想把一個指針傳給一個函數。在這個函數中我使用了malloc來保留空間。問題是當我在main函數中返回時,程序沒有響應。這裏是我的代碼Symplified公司:在函數裏面的malloc用法

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
int def(char **B){ 
    int i; 
    B = malloc(3 * sizeof(char)); 
    for(i = 0; i < 2 ; i++){ 
     B[i] = malloc(5 * sizeof(char)); 
    } 
    for(i = 0; i < 2 ; i++){ 
     scanf("%s" , B[i]); 
    } 
    for(i = 0; i < 2 ; i++){ 
     printf("%s\n" , B[i]); 
    } 
    return 0; 
} 

int main(int argc, char *argv[]) { 
    char **B; 
    int i; 
    def(B); 
    for(i = 0; i < 2 ; i++){ 
     printf("%s\n" , B[i]); 
    } 
    return 0; 
} 
+1

請縮進代碼; –

+0

當你完成它時,你需要在指針上調用free()。 – Samuel

+0

請勿使用幻數。如果您必須使用'#define'對代碼進行硬編碼,以便每個用法都引用單個定義。這樣一來,爲內存分配的元素數量就不會那麼容易,而且代碼將很容易維護。而且,你是否意識到只能在不受限制的'scanf'語句中輸入一個4個字符的字符串。 –

回答

2
int def(char **B) 

應該已經

char** def(char **B) 

和它的返回值應該是

return B; 
/* else the memory allocated inside the function will be freed at 
    * the end and by accessing it later you have undefined behavior for the 
    * rest of the program 
    */ 


B = malloc(3 * sizeof(char)); 

應該已經

B = malloc(3 * sizeof(char*)); // you have two levels of indirection. so char* first 


for(i = 0; i < 2 ; i++) // similary with the other for loops 

應該已經

for(i = 0; i < 3 ; i++) // you used 3 in the above step 


def(B); 

應該已經

B=def(B); 

它是用free()釋放所分配的內存,雖然它會在程序結束時自動釋放一個很好的做法

+0

這不能解決問題。所有這些都是分配一堆內存,當函數返回時會丟失這些內存。 –

+0

@TomKarzes:沒有注意到,在乞討。但現在修好了 – sjsam

+0

'B = def(B);' - 真的嗎?傳遞'B'毫無意義。此外,由於您需要編寫一個很好的答案,請提及malloc可能會失敗,即測試返回值。 – 4386427

0

你似乎試圖分配一個字符串列表,但是您不提供在def函數之外引用該字符串的能力。你的問題的第一部分是,你必須提供一個指向您的列表:

int def(char ***B) { 

另一種選擇是回到您創建的指針:在你分配你的第一個的malloc其次

char** def() { 

空間爲3 chars但你需要char指針。 sizeof char != sizeof char*

B = malloc(3 * sizeof(char)); 

應該是:

*B = malloc(3 * sizeof char*); 

而且你應該使用const int#define來定義你的尺寸的常數,所以你不小心在不同的地方得到錯誤的大小,例如。

#define SIZE_OF_LIST 3 
int def(char ***B){ 
    int i; 
    B = malloc(SIZE_OF_LIST * sizeof(char)); 
    for(i = 0; i < SIZE_OF_LIST ; i++){ 

最後,當你通過函數指針def你需要這樣做(上適應第一個變化):

def(&B); 

B = def(); 
+0

這不能解決問題。所有這些都是分配一堆內存,當函數返回時會丟失這些內存。 –

+0

@TomKarzes在您評論,修正之前,我意識到這一點。 –

1

似乎您試圖malloc看起來像一個二維數組(或者說是一個字符串數組)的東西。

然而,

def(B); 

是價值的看漲所以B不改變函數返回時。

如果你想改變B需要

def(&B); 

,然後你需要修改相應的函數簽名 - 那麼你會一個三星級的程序員。

如果你想這樣做,正確的,那麼閱讀:

Create 2D array by passing pointer to function in c

和閱讀@Lundin給出了答案 - 這就是做

+0

然後這些類型是錯誤的。這是一個非常不完整的答案。 –

+0

@TomKarzes - 確切地說,這是代碼問題的第2步 – 4386427

+0

引入第三級間接引用而不是'返回'指針從函數到'main'。 – ameyCU

0

其實,這是比這更糟糕的方式。所有C函數參數都是「按值」,這意味着函數內部的變量是在調用時傳入的變量的本地副本。所以,當你給一個參數賦值時(你可以這樣做,除非它被聲明爲'const'[我認爲C++的'const'現在已經被C採用了]),你不是賦值給變量在通話中傳遞。因此,在這種情況下,聲明

B = malloc(3 * sizeof(char *)); 

不會改變指針的B 的main()宣佈;它只是泄漏內存。假設你真的需要這個功能返回INT,則需要添加間接的層次:

int def(char ***B){ 
    *B = malloc(3 * sizeof(char *)); 
    for(i=0; i<2; i++){ 
     (*B)[i] = malloc(5 * sizeof(char)); 
    } 
    ... 
} 

... 

char **B; 
... 
def(&B); /* Note the 'address-of' operator! */ 

如果返回不必是INT:消除參數高清( ),將其更改爲返回**** char **,直接返回第一個malloc()的結果,並將呼叫更改爲B = def();

0

您的問題是,當你調用def(B),你正在創建一個char **這是一個複製的B。如果更改此新的B,則更改不會反映在主功能上,因爲它們是由B的副本製作的。

您應該使用char ***並調用def(&B)(我不認爲這是一個好辦法,壽),或者你可以有B在主初始化,並呼籲def(B)到alloc和讀取其char *,或者你可以返回新B

此外,請檢查其他答案中指出的問題。