2011-10-28 68 views
0

我想提供一個函數,然後用東西填充它的字符指針,以便調用函數可以使用它。因爲它總是給我奇怪的東西在調用函數中我寫了什麼,我做了簡單的表示:如何通過一個指針並分配堆上的空間

#include <stdio.h> 
#include <stdlib.h> 

void bla(char *t) 
{ 
    t = (char*) malloc(5); 
    if (t != 0) { 
     t[0] = 'h'; 
     printf("%c\n", t[0]); 
    } 
} 

int main(int argc, char **argv) 
{ 
    char b[10]; 

    bla(b); 
    printf("%c\n", b[0]); 
    return 1; 
} 

我不太清楚,如果有事情做的是C已通過參數的副本。我需要將指針傳遞給指針嗎還是有更好的解決方案?

編輯:

對不起,但我沒有得到它。你能看看這個例子:

#include <stdio.h> 
#include <stdlib.h> 

void blub(char **t) 
{ 
    printf("%d\n", *t); 
    *t = (char*) malloc(sizeof(char) * 5); 
    *t[0] = 'a'; 
    *t[1] = 'b'; 
    printf("%d\n", *t); 
    printf("%d\n", *t[0]); 
    printf("%d\n", *t[1]); 
} 

int main(int argc, char **argv) 
{ 
    char *a; 
    blub(&a); 
    printf("%d\n", a); 
    printf("%d\n", a[0]); 
    printf("%d\n", a[1]); 

    return 1; 
} 

輸出如下:

./main 
6154128 
140488712 
97 
98 
140488712 
97 
0  <== THIS SHOULD BE 98 AS ABOVE!? 

爲什麼我得到的功能blafu 98和主要它是一個空指針?我很困惑:/

+0

該代碼沒什麼意義... –

+1

不要忘記釋放你的記憶! – Nick

+0

@pluckyDuck - 看我的編輯:)你是在正確的方向。 –

回答

7

你需要使用指針指針。

//............vv 
void bla(char **t) 

然後通過解引用它使用指針:

// note the '*' in front of t 
*t = (char*) malloc(5); 
if (*t != 0) { 
    *t[0] = 'h'; 
    printf("%c\n", *t[0]); 
} 

另外,聲明bchar*,而不是作爲char b[10]


爲什麼?因爲你正試圖改變指針。邏輯與其他類型相同,但這裏有點混亂。
想想這樣:如果你需要通過一個int並且你需要改變它,你需要一個指向int的指針。同樣是在這裏 - 你需要傳遞一個字符指針,你需要改變喲,所以用「指針字符指針」 :)


編輯: 根據你的編輯 - 是的,你完全理解這一點,這只是一個小問題 - 優先operator*operator[]。如果您*t[X](*t)[X]取代,當你寫char b[10];你有一個靜態分配的數組,你並不需要分配更多的空間,它是適合容納多達10 everythng將被罰款:)

+0

你拯救了我的生命:) – pluckyDuck

0

值爲char

如果你想讓你的函數修改數組,你只需要通過一個簡單的指針的內容,你都做到了(但沒有配置!):

void bla(char *t) 
{ 
    if (t != 0) { 
     t[0] = 'h'; 
     printf("%c\n", t[0]); 
    } 
} 

的功能後,您的main中的b的值也會更改。

+0

它只是真正的問題的模型,我需要使用malloc。 – pluckyDuck

2

如果你使用指針的指針

void blah(char **t) 

您可以使用malloc作爲

*t = malloc(size); 

分配的內存chunck(在頭),你會打電話等等這樣的:

char *b; 
bla(&b); 

它將被分配和填充使用等等,結果可以打印在主要。

0

如果你想使用var引用返回結果,那麼你需要傳遞一個指針指向一個指針(或者只是以通常的方式返回結果char * bla())。不要忘記null結束符!

1

您正在傳遞指向函數的指針。通過它,你可以永久地改變(在函數返回之後)它所指向的對象,但是你不能改變指針本身,因爲它是實際傳遞給函數的副本。函數內的所有更改都是在指針的副本上進行的。函數返回時其原始值保持不變。 (1)如果你想在一些函數中改變一些變量,你需要將它的指針傳遞給它。如果該變量是指針類型的,則將指針傳遞給它 - 指向指針的指針!在你的情況下,該變量將是char **類型。 (2)如果你想在函數的堆中分配內存,你不需要使用堆棧 - 將指針b聲明爲char *。 (3)在堆上分配內存之後,不要忘記取消分配它,否則最終會發生內存泄漏。

(4)如果應用程序終止且沒有錯誤,則返回0。爲錯誤代碼保留其他返回值 - 如果您的應用中可能出現不同的錯誤,則返回不同的代碼。

最後一點是,這是一個純粹的C應用程序。在C++中,你將使用新/刪除分配/釋放內存,的std :: string代替字符*字符串,和std ::法院< <代替了printf發送文本輸出流

void bla(char **pt)    // (1) 
{ 
    *pt = (char*)malloc(5); 

    if (*pt != 0) 
    { 
     *pt[0] = 'h'; 
     printf("%c\n", *pt[0]); 
    } 
} 

int main(int argc, char **argv) 
{ 
    char* b = 0;     // (2) 

    bla(&b); 
    printf("%c\n", b[0]); 

    if(b) 
    { 
     free(b);     // (3) 
     b = 0; 
    } 

    return 0;      // (4) 
} 
0

的第二個例子中奇怪行爲的原因是操作員的優先級。 [](括號,數組下標)具有比*更高的優先級(解引用)

所以,*t[1]相同*(t[1]).需要(*t)[1]

爲t是指向字符指針:

*(t[1])意味着「取得t的地址,前進(sizeof(char *))字節,取消引用地址,並且解除引用」

(*t)[1]意思是「取得t的地址,取消引用它,去(sizeof(char))字節提前並取消e再次「

實際上,在第一種情況下,行爲是未定義的,因爲它試圖在t之後將位置加倍去保護。在你的例子中,第一個值總是會被​​打印出來,因爲t [0]意味着只有解引用,所以這兩種情況將是相同的。

相關問題