2013-03-28 66 views
0

我是C語言的初學者,我無法很好理解的是malloc的使用。所以我決定創建這個例子。我想了解爲什麼它不打印出緩衝區數據,以及最佳做法是什麼。爲什麼c指針在這裏不起作用?

#include <stdio.h>  /* printf, scanf, NULL */ 
#include <stdlib.h>  /* malloc, free, rand */ 

void f(char * buffer, int i) { 
    buffer = (char *) malloc(i+1); 
    if (buffer==NULL) 
    exit (1); 

    for (int n=0; n<i; n++) 
    buffer[n]=rand()%26+'a'; 

    buffer[i]='\0'; 
} 

int main() 
{ 
    char * buffer; 
    f(buffer, 5); 
    printf ("Random string: %s\n",buffer); 
    free (buffer); 

    return 0; 
} 

感謝

+0

是否打印 「隨機字符串:」? –

+0

是...它打印 –

回答

4

buffer = (char *) malloc(i+1);所具有的功能之外沒有影響。實際上,該功能正在更改自己的buffer副本,而主叫方(main)從未看到此更改。這在C FAQ中得到了很好的解釋。

而是將它作爲一個參數,你可以返回緩衝區,因爲函數不會在瞬間返回任何東西:

char *f(int i) 
    /* ... */ 
    return buffer; 

/* ... */ 

char * buffer = f(5); 

  • 在C鑄造malloc是不必要的,並且經常被認爲是 可疑練習
  • ni變量名有點誤導:一個人期望他們相反
  • f不是GOOT名稱功能
+0

我的疑問是,如果我在函數範圍內創建一個指針,返回它,它將在函數外保持有效?我的意思是,在函數結束時,指針不再存在... –

+0

@Leandro你是對的擔心。但是這樣想:指針本身不再存在,這是肯定的。但在它被破壞之前,它設法傳達其內容,實際上是一個地址。所以現在有人('main'的'buffer')擁有這個地址。 **所以它是安全的**,'f'可以安全地殺死所有的局部變量。 – cnicutar

+0

謝謝@cnicutar,它幫助我太多了。太謝謝你了! –

2

爲了修改指針傳遞給函數,你必須使用指針的指針:

void f(char** buffer, int i) { 
    *buffer = malloc(i+1); 
    if (*buffer==NULL) 
    exit (1); 

    for (int n=0; n<i; n++) 
    (*buffer)[n]=rand()%26+'a'; 

    (*buffer)[i]='\0'; 
} 

用法:

char* buff; 

f(&buff, len); 
+1

不要忘了提及如何將緩衝區傳遞給函數。 – 2013-03-28 15:18:05

+0

謝謝亞歷克斯。我想知道,如果這是這種類型的問題的最佳做法... –

+0

@Armin修復,謝謝 – Alex

1

變量是通過值傳遞給函數。

當您撥打f(buffer, 5)時,它不會將變量buffer傳遞給功能f;它只複製變量buffer的值。在函數f中,創建了一個名爲buffer(參數變量)的新變量。當您更改該變量的值時,從main傳入的原始變量不受影響。

不同的方法來解決這個問題:

製作f返回指針,並將其保存在buffermain

char * f(int i) { 
    char * buffer = malloc(i + 1); 

    /* ... */ 

    return buffer; 
} 

int main() { 
    char * buffer = f(5); 

    /* ... */ 

    return 0; 
} 

還是一個指針傳遞給一個指針f;在main,合格buffer地址:

void f(char ** buffer, int i) { 
    *buffer = malloc(i + 1); 

    /* ... */ 
} 

int main() { 
    char * buffer; 
    f(&buffer, 5); 

    /* ... */ 

    return 0; 
}   
0

你不能改變的變量的原始值是通過按值

如果你想在一個函數的malloc,並在一個變量返回的malloc的結果,那麼該變量必須是通過按引用

E.g.而不是:

void f(char * buffer, int i); 

它應該是:

void f(char **buffer, int i); 
0

CNICUTAR是正確的,但在這裏是有趣的信息:

MALLOC:

不要投的malloc(這裏是一個有趣的話題:Do I cast the result of malloc?)。

FOR循環:

對於for循環,你應該用這樣的方式(C89版):

int i; 
for (i = 0; ...) 

問候,

+0

感謝提示Joze! –

相關問題